In [ ]:
# %matplotlib widget

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# setup latex style for plots exported to svg
plt.rcParams['svg.fonttype'] = 'none'
import matplotlib_inline.backend_inline
matplotlib_inline.backend_inline.set_matplotlib_formats('svg')

# set legend text with prop={'size': 8} globally
plt.rc('legend', fontsize=8)

Anti-backlash test data¶

In [ ]:
def average_test_repetitions(df, groupby):
    data = []
    grouped = df.groupby(groupby)

    for name, group in grouped:
        group = group.drop(groupby, axis=1)
        group.index = group.index - group.index[0]

        old_len = len(group)
        group = group.resample('0.5ms').mean()
        group = group.interpolate(method='time')
        # print(f'test {name} resampled from {old_len} to {len(group)} samples')

        data.append(group.values)

    # get consistent length
    min_len = min([len(d) for d in data])
    data = [d[:min_len] for d in data]
    # print(f'setting everything to {min_len} samples')

    # average data using numpy
    data_mean = np.mean(np.array(data), axis=0)

    new_columns = df.columns.drop(groupby)
    mean_df = pd.DataFrame(data_mean, columns=new_columns)

    time_index = pd.timedelta_range(start=0, periods=min_len, freq='0.5ms')
    mean_df.index = time_index

    # smooth data
    mean_df = mean_df.rolling(window=100, center=True).mean()
    mean_df = mean_df.bfill().ffill()

    return mean_df


class actuator_test_data:
    def __init__(self, configuration='...'):
        self.configuration = configuration
        self.raw_torque_ramps = {}
        self.torque_ramps = {}
        self.speed_ramps = {}
        self.runin_tests = []

        
    def add_test_moment(self, phase, files):
        torque_ramp_files = [f for f in files if 'torqueramp' in f]
        speed_ramp_files = [f for f in files if 'speedramp' in f]
        
        if torque_ramp_files:
            self.add_torque_ramps(phase, torque_ramp_files)
        
        for file in speed_ramp_files:
            self.add_speed_ramp(phase, file)

    def add_torque_ramps(self, name, files):
        torque_ramps = {}
        for i, filename in enumerate(files):
            df_raw = pd.read_csv(filename)
            # print(f'{filename} loaded\t {list(df_raw.columns)}')

            df = pd.DataFrame()
            df['Time [s]'] = df_raw['TIME']
            df['Motor Torque [Nm]'] = df_raw['TORQUE']
            df['Deflection [deg]'] = df_raw['POSITION'] * 360
            df['Desired Torque [Nm]'] = df_raw['CONTROL_TORQUE']
            df['Motor Q_current [A]'] = df_raw['Q_CURRENT']
            df['test_nr'] = df_raw['test_nr']

            # print(f'Sample rate: {1/(df["Time [s]"].diff().mean())} Hz')
            df['Time [s]'] = pd.to_timedelta(df['Time [s]'], unit='s')
            df.set_index('Time [s]', inplace=True)

            self.raw_torque_ramps[name] = df

            print(f"loaded {filename}.\t Test postion: {df['Deflection [deg]'].mean():5.2f} deg")
            df['Deflection [deg]'] -= df['Deflection [deg]'].mean()
            
            TEST_NR_OFFSET = 100
            play_tests = df[df['test_nr'] < TEST_NR_OFFSET].copy()
            stiffness_tests = df[df['test_nr'] >= TEST_NR_OFFSET].copy()
            stiffness_tests['test_nr'] = stiffness_tests['test_nr'] - TEST_NR_OFFSET

            play_test_mean = average_test_repetitions(play_tests, 'test_nr')
            stiffness_test_mean = average_test_repetitions(stiffness_tests, 'test_nr')

            # shift to around 0, subtract mean
            play_test_mean['Deflection [deg]'] -= play_test_mean['Deflection [deg]'].mean()
            stiffness_test_mean['Deflection [deg]'] -= stiffness_test_mean['Deflection [deg]'].mean()

            torque_ramps[i] = (play_test_mean, stiffness_test_mean)

        test_pos = 0
        combined_play = None
        combined_stiffness = None
        for i, (play_test, stiffness_test) in torque_ramps.items():
            play_test['test_pos'] = test_pos
            stiffness_test['test_pos'] = test_pos
            test_pos += 1

            if combined_play is None:
                combined_play = play_test
                combined_stiffness = stiffness_test
            else:
                combined_play = pd.concat([combined_play, play_test])
                combined_stiffness = pd.concat([combined_stiffness, stiffness_test])

        combined_play = average_test_repetitions(combined_play, 'test_pos')
        combined_stiffness = average_test_repetitions(combined_stiffness, 'test_pos')
        combined_play['Deflection [deg]'] -= combined_play['Deflection [deg]'].mean()
        combined_stiffness['Deflection [deg]'] -= combined_stiffness['Deflection [deg]'].mean()
        torque_ramps['combined'] = (combined_play, combined_stiffness)    

        self.torque_ramps[name] = torque_ramps

    def add_speed_ramp(self, name, filename):
        df_raw = pd.read_csv(filename)

        df = pd.DataFrame()
        df['Motor Speed [rpm]'] = df_raw['VELOCITY']
        df['Motor Torque [Nm]'] = df_raw['TORQUE']
        df['Averaged Torque [Nm]'] = df['Motor Torque [Nm]'].rolling(window=500, center=True).mean()
        df['Motor Q_current [A]'] = df_raw['Q_CURRENT']

        df['Time [s]'] = pd.to_timedelta(df_raw['TIME'], unit='s')
        df.set_index('Time [s]', inplace=True)  
        
        print(f'loaded {filename}.')
        self.speed_ramps[name] = df

    def add_runin_tests(self, files):
        def read_file(filename):
            df_raw = pd.read_csv(filename, sep=';')
            
            if 'DIRECTION' not in df_raw.columns:
                # df_raw['TIME'] /= 1e9
                df_raw['DIRECTION'] = 1
            df = pd.DataFrame()
            df['Motor Torque [Nm]'] = df_raw['TORQUE']  # * df_raw['DIRECTION']
            df['Averaged Torque [Nm]'] = df['Motor Torque [Nm]'].rolling(window=100, center=True).mean()
            df['Motor Temperature [c]'] = df_raw['MOTOR_TEMPERATURE'] *0.442 - 1.62   #approximation to compensate incorrect NTC
            df['Controller Temperature [c]'] = df_raw['TEMPERATURE']
            
            df_raw['TIME'] = (df_raw['TIME'] - df_raw['TIME'].iloc[0]) / 1e9
            df['Time [s]'] = pd.to_timedelta(df_raw['TIME'], unit='s')
            df.set_index('Time [s]', inplace=True)
            
            return df

        df = read_file(files[0])
        df['test number'] = 0
        for filename in files[1:]:
            df2 = read_file(filename)
            df2.index = df2.index + df.index[-1] + pd.Timedelta(1, unit='ms')
            df2['test number'] = df['test number'].iloc[-1] + 1
            df = pd.concat([df, df2])

        print(f'loaded {len(files)} run-in tests, measured time: {df.index[-1]}')

        self.runin_tests = df

    def describe(self):
        print(f'Configuration: {self.configuration}')
        print(f'Speed ramps: {list(self.speed_ramps.keys())}')
        print(f'Torque ramps:')
        for name, ramps in self.torque_ramps.items():
            print(f'  {name}: {len(ramps)} ramps ({ramps.keys()})')
        print(f'Run-in tests: {self.runin_tests["test number"].max()+1} tests, total time: {self.runin_tests.index[-1]}')
In [ ]:
tests_split_pccf_u = actuator_test_data('Split Pinwheel undersized (PC-CF)')
tests_split_pccf_u.add_test_moment('initial', [
    'test_data/2024-07-10__12-06-49_speedramp_split init_120s.csv',
    # 'test_data/2024-07-10__12-30-32__torqueramp__split init1.csv',
    'test_data/2024-07-10__12-34-04__torqueramp__split init1.csv',
    'test_data/2024-07-10__12-39-58__torqueramp__split init5.csv',
    'test_data/2024-07-10__12-45-53__torqueramp__split init6.csv', 
])
tests_split_pccf_u.add_runin_tests([
    'test_data/2024-07-10__15-56-23_run-in_split_0.35rps.csv',
])
tests_split_pccf_u.add_test_moment('after run-in', [
    'test_data/2024-07-10__16-10-16_speedramp_split 10min_120s.csv',
    'test_data/2024-07-10__16-27-11__torqueramp__split runin1.csv',
    'test_data/2024-07-10__16-31-56__torqueramp__split runin5.csv',
    'test_data/2024-07-10__16-35-37__torqueramp__split runin6.csv',
    # 'test_data/2024-07-10__16-39-51_speedramp_split runin_120s.csv',
])
tests_split_pccf_u.add_test_moment('preload increase 1', [
    'test_data/2024-07-10__16-44-11_speedramp_split 1pre_120s.csv',
    'test_data/2024-07-10__16-48-09__torqueramp__split 1pre1.csv',
    'test_data/2024-07-10__16-52-42__torqueramp__split 1pre5.csv',
    'test_data/2024-07-10__16-58-03__torqueramp__split 1pre6.csv',
])

    # 'test_data/2024-07-11__11-11-47_speedramp_split 2pre_120s.csv',
    # 'test_data/2024-07-11__11-17-34_speedramp_split 1.5pre_120s.csv',
tests_split_pccf_u.add_test_moment('preload increase 2', [
    'test_data/2024-07-11__11-26-10_speedramp_split 2pre_120s.csv',
    'test_data/2024-07-11__11-32-34__torqueramp__split 2pre1.csv',
    'test_data/2024-07-11__11-37-19__torqueramp__split 2pre5.csv',
    'test_data/2024-07-11__11-42-35__torqueramp__split 2pre6.csv',
])
tests_split_pccf_u.add_test_moment('preload increase 3', [
    'test_data/2024-07-11__12-18-00_speedramp_split 3pre_120s.csv',
    'test_data/2024-07-11__12-24-10__torqueramp__split 3pre1.csv',
    'test_data/2024-07-11__12-29-25__torqueramp__split 3pre5.csv',
    'test_data/2024-07-11__12-43-57__torqueramp__split 3pre6.csv',
])
tests_split_pccf_u.add_test_moment('preload increase 4', [
    'test_data/2024-07-11__13-20-23_speedramp_split 4pre_120s.csv',
    'test_data/2024-07-11__13-26-36__torqueramp__split 4pre1.csv',
    'test_data/2024-07-11__13-42-44__torqueramp__split 4pre5.csv',
    'test_data/2024-07-11__13-46-33__torqueramp__split 4pre6.csv',
])
tests_split_pccf_u.add_test_moment('preload increase 5', [
        'test_data/2024-07-11__13-51-30_speedramp_split 5pre_120s.csv',
])

print('\n')
tests_split_pccf_u.describe()
loaded test_data/2024-07-10__12-34-04__torqueramp__split init1.csv.	 Test postion: 11.16 deg
loaded test_data/2024-07-10__12-39-58__torqueramp__split init5.csv.	 Test postion: -2.97 deg
loaded test_data/2024-07-10__12-45-53__torqueramp__split init6.csv.	 Test postion:  7.38 deg
loaded test_data/2024-07-10__12-06-49_speedramp_split init_120s.csv.
loaded 1 run-in tests, measured time: 0 days 00:10:12.434426100
loaded test_data/2024-07-10__16-27-11__torqueramp__split runin1.csv.	 Test postion:  3.72 deg
loaded test_data/2024-07-10__16-31-56__torqueramp__split runin5.csv.	 Test postion: -9.84 deg
loaded test_data/2024-07-10__16-35-37__torqueramp__split runin6.csv.	 Test postion:  0.26 deg
loaded test_data/2024-07-10__16-10-16_speedramp_split 10min_120s.csv.
loaded test_data/2024-07-10__16-48-09__torqueramp__split 1pre1.csv.	 Test postion:  3.91 deg
loaded test_data/2024-07-10__16-52-42__torqueramp__split 1pre5.csv.	 Test postion: -8.87 deg
loaded test_data/2024-07-10__16-58-03__torqueramp__split 1pre6.csv.	 Test postion:  0.49 deg
loaded test_data/2024-07-10__16-44-11_speedramp_split 1pre_120s.csv.
loaded test_data/2024-07-11__11-32-34__torqueramp__split 2pre1.csv.	 Test postion:  3.99 deg
loaded test_data/2024-07-11__11-37-19__torqueramp__split 2pre5.csv.	 Test postion: -9.65 deg
loaded test_data/2024-07-11__11-42-35__torqueramp__split 2pre6.csv.	 Test postion:  0.86 deg
loaded test_data/2024-07-11__11-26-10_speedramp_split 2pre_120s.csv.
loaded test_data/2024-07-11__12-24-10__torqueramp__split 3pre1.csv.	 Test postion:  3.67 deg
loaded test_data/2024-07-11__12-29-25__torqueramp__split 3pre5.csv.	 Test postion: -9.87 deg
loaded test_data/2024-07-11__12-43-57__torqueramp__split 3pre6.csv.	 Test postion: -0.06 deg
loaded test_data/2024-07-11__12-18-00_speedramp_split 3pre_120s.csv.
loaded test_data/2024-07-11__13-26-36__torqueramp__split 4pre1.csv.	 Test postion:  3.88 deg
loaded test_data/2024-07-11__13-42-44__torqueramp__split 4pre5.csv.	 Test postion: -9.58 deg
loaded test_data/2024-07-11__13-46-33__torqueramp__split 4pre6.csv.	 Test postion:  0.50 deg
loaded test_data/2024-07-11__13-20-23_speedramp_split 4pre_120s.csv.
loaded test_data/2024-07-11__13-51-30_speedramp_split 5pre_120s.csv.


Configuration: Split Pinwheel undersized (PC-CF)
Speed ramps: ['initial', 'after run-in', 'preload increase 1', 'preload increase 2', 'preload increase 3', 'preload increase 4', 'preload increase 5']
Torque ramps:
  initial: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  after run-in: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 1: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 2: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 3: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 4: 4 ramps (dict_keys([0, 1, 2, 'combined']))
Run-in tests: 1 tests, total time: 0 days 00:10:12.434426100
In [ ]:
tests_base_pccf = actuator_test_data('Baseline (PC-CF)')
tests_base_pccf.add_test_moment('initial', [
    'test_data/2024-07-11__14-38-26_speedramp_base init_120s.csv',
    # 'test_data/2024-07-11__14-44-21__torqueramp__base init1.csv',
    # 'test_data/2024-07-11__14-50-03__torqueramp__base init5.csv',         # locking plate not fixed correctly
    'test_data/2024-07-11__14-54-07__torqueramp__base init1.csv',
    'test_data/2024-07-11__14-59-51__torqueramp__base init5.csv',
    'test_data/2024-07-11__15-06-17__torqueramp__base init6.csv',
])
tests_base_pccf.add_runin_tests([
    'test_data/2024-07-11__15-12-31_run-in_base_0.35rps.csv',
])
tests_base_pccf.add_test_moment('after run-in', [
    'test_data/2024-07-11__15-26-00_speedramp_base runin_120s.csv',
    'test_data/2024-07-11__15-47-12__torqueramp__base runin1.csv',
    'test_data/2024-07-11__15-51-51__torqueramp__base runin5.csv',
    'test_data/2024-07-11__15-56-27__torqueramp__base runin6.csv',
])

print('\n')
tests_base_pccf.describe()
loaded test_data/2024-07-11__14-54-07__torqueramp__base init1.csv.	 Test postion:  1.37 deg
loaded test_data/2024-07-11__14-59-51__torqueramp__base init5.csv.	 Test postion: -11.85 deg
loaded test_data/2024-07-11__15-06-17__torqueramp__base init6.csv.	 Test postion: -1.79 deg
loaded test_data/2024-07-11__14-38-26_speedramp_base init_120s.csv.
loaded 1 run-in tests, measured time: 0 days 00:11:11.191207800
loaded test_data/2024-07-11__15-47-12__torqueramp__base runin1.csv.	 Test postion:  1.58 deg
loaded test_data/2024-07-11__15-51-51__torqueramp__base runin5.csv.	 Test postion: -12.11 deg
loaded test_data/2024-07-11__15-56-27__torqueramp__base runin6.csv.	 Test postion: -1.66 deg
loaded test_data/2024-07-11__15-26-00_speedramp_base runin_120s.csv.


Configuration: Baseline (PC-CF)
Speed ramps: ['initial', 'after run-in']
Torque ramps:
  initial: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  after run-in: 4 ramps (dict_keys([0, 1, 2, 'combined']))
Run-in tests: 1 tests, total time: 0 days 00:11:11.191207800
In [ ]:
tests_conic_pccf = actuator_test_data('Conic Disk (PC-CF)')
tests_conic_pccf.add_test_moment('initial', [
    'test_data/2024-07-12__11-25-30_speedramp_conic init_120s.csv',
    'test_data/2024-07-12__11-33-31__torqueramp__conic init1.csv', 
    'test_data/2024-07-12__12-23-01__torqueramp__conic init5.csv',
    'test_data/2024-07-12__12-29-20__torqueramp__conic init6.csv',
])
tests_conic_pccf.add_runin_tests([
    'test_data/2024-07-12__12-40-29_run-in_conic_0.35rps.csv',
    'test_data/2024-07-12__12-55-01_run-in_conic_0.35rps.csv',
])
tests_conic_pccf.add_test_moment('after run-in', [
    'test_data/2024-07-12__12-57-37_speedramp_conic runin_120s.csv',
    'test_data/2024-07-12__13-05-47__torqueramp__conic runin1.csv',
    'test_data/2024-07-12__13-16-01__torqueramp__conic runin5.csv',
    'test_data/2024-07-12__13-32-22__torqueramp__conic runin6.csv',
])
tests_conic_pccf.add_test_moment('preload increase 1', [
    'test_data/2024-07-12__13-58-40_speedramp_conic 1pre_120s.csv',
    'test_data/2024-07-12__14-07-48__torqueramp__conic 1pre1.csv',
    'test_data/2024-07-12__14-26-23__torqueramp__conic 1pre5.csv',
    'test_data/2024-07-12__14-31-48__torqueramp__conic 1pre6.csv',
])
tests_conic_pccf.add_test_moment('preload increase 2', [
    'test_data/2024-07-12__14-45-16_speedramp_conic 2pre_120s.csv',
    'test_data/2024-07-12__14-52-50__torqueramp__conic 2pre1.csv',
    'test_data/2024-07-12__14-57-29__torqueramp__conic 2pre5.csv',
    'test_data/2024-07-12__15-12-22__torqueramp__conic 2pre6.csv',
])
tests_conic_pccf.add_test_moment('preload increase 3', [
    'test_data/2024-07-12__16-18-48_speedramp_conic 3pre_120s.csv',
    'test_data/2024-07-12__16-23-23__torqueramp__conic 3pre1.csv',
    'test_data/2024-07-12__16-34-37__torqueramp__conic 3pre5.csv',
    'test_data/2024-07-12__16-28-44__torqueramp__conic 3pre6.csv',
])
tests_conic_pccf.add_test_moment('preload increase 4', [
    'test_data/2024-07-12__16-41-31_speedramp_conic 4pre_120s.csv',
    'test_data/2024-07-12__16-46-43__torqueramp__conic 4pre1.csv',
    'test_data/2024-07-12__16-57-04__torqueramp__conic 4pre5.csv',
    'test_data/2024-07-12__16-51-38__torqueramp__conic 4pre6.csv',
])
tests_conic_pccf.add_test_moment('preload increase 5', [
    'test_data/2024-07-12__17-03-46_speedramp_conic 5pre_120s.csv',
    'test_data/2024-07-12__17-09-01__torqueramp__conic 5pre1.csv',
    'test_data/2024-07-12__17-17-36__torqueramp__conic 5pre5.csv', 
    'test_data/2024-07-12__17-13-06__torqueramp__conic 5pre6.csv',
])

print('\n')
tests_conic_pccf.describe()
loaded test_data/2024-07-12__11-33-31__torqueramp__conic init1.csv.	 Test postion:  6.46 deg
loaded test_data/2024-07-12__12-23-01__torqueramp__conic init5.csv.	 Test postion: -8.41 deg
loaded test_data/2024-07-12__12-29-20__torqueramp__conic init6.csv.	 Test postion:  1.71 deg
loaded test_data/2024-07-12__11-25-30_speedramp_conic init_120s.csv.
loaded 2 run-in tests, measured time: 0 days 00:12:27.924977900
loaded test_data/2024-07-12__13-05-47__torqueramp__conic runin1.csv.	 Test postion:  5.06 deg
loaded test_data/2024-07-12__13-16-01__torqueramp__conic runin5.csv.	 Test postion: -7.95 deg
loaded test_data/2024-07-12__13-32-22__torqueramp__conic runin6.csv.	 Test postion:  2.47 deg
loaded test_data/2024-07-12__12-57-37_speedramp_conic runin_120s.csv.
loaded test_data/2024-07-12__14-07-48__torqueramp__conic 1pre1.csv.	 Test postion:  5.70 deg
loaded test_data/2024-07-12__14-26-23__torqueramp__conic 1pre5.csv.	 Test postion: -8.12 deg
loaded test_data/2024-07-12__14-31-48__torqueramp__conic 1pre6.csv.	 Test postion:  2.82 deg
loaded test_data/2024-07-12__13-58-40_speedramp_conic 1pre_120s.csv.
loaded test_data/2024-07-12__14-52-50__torqueramp__conic 2pre1.csv.	 Test postion:  5.28 deg
loaded test_data/2024-07-12__14-57-29__torqueramp__conic 2pre5.csv.	 Test postion: -8.30 deg
loaded test_data/2024-07-12__15-12-22__torqueramp__conic 2pre6.csv.	 Test postion:  2.56 deg
loaded test_data/2024-07-12__14-45-16_speedramp_conic 2pre_120s.csv.
loaded test_data/2024-07-12__16-23-23__torqueramp__conic 3pre1.csv.	 Test postion:  5.46 deg
loaded test_data/2024-07-12__16-34-37__torqueramp__conic 3pre5.csv.	 Test postion: -8.25 deg
loaded test_data/2024-07-12__16-28-44__torqueramp__conic 3pre6.csv.	 Test postion:  2.13 deg
loaded test_data/2024-07-12__16-18-48_speedramp_conic 3pre_120s.csv.
loaded test_data/2024-07-12__16-46-43__torqueramp__conic 4pre1.csv.	 Test postion:  6.43 deg
loaded test_data/2024-07-12__16-57-04__torqueramp__conic 4pre5.csv.	 Test postion: -7.40 deg
loaded test_data/2024-07-12__16-51-38__torqueramp__conic 4pre6.csv.	 Test postion:  3.35 deg
loaded test_data/2024-07-12__16-41-31_speedramp_conic 4pre_120s.csv.
loaded test_data/2024-07-12__17-09-01__torqueramp__conic 5pre1.csv.	 Test postion:  6.53 deg
loaded test_data/2024-07-12__17-17-36__torqueramp__conic 5pre5.csv.	 Test postion: -7.05 deg
loaded test_data/2024-07-12__17-13-06__torqueramp__conic 5pre6.csv.	 Test postion:  3.63 deg
loaded test_data/2024-07-12__17-03-46_speedramp_conic 5pre_120s.csv.


Configuration: Conic Disk (PC-CF)
Speed ramps: ['initial', 'after run-in', 'preload increase 1', 'preload increase 2', 'preload increase 3', 'preload increase 4', 'preload increase 5']
Torque ramps:
  initial: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  after run-in: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 1: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 2: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 3: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 4: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 5: 4 ramps (dict_keys([0, 1, 2, 'combined']))
Run-in tests: 2 tests, total time: 0 days 00:12:27.924977900
In [ ]:
tests_split_pccf = actuator_test_data('Split Pinwheel (PC-CF)') 
tests_split_pccf.add_test_moment('initial', [
    'test_data/2024-07-15__14-09-03_speedramp_split init_120s.csv',
    'test_data/2024-07-15__14-17-32__torqueramp__split init1.csv',
    'test_data/2024-07-15__14-26-05__torqueramp__split init5.csv',
    'test_data/2024-07-15__14-35-07__torqueramp__split init6.csv',
])
tests_split_pccf.add_runin_tests([
    'test_data/2024-07-15__14-49-39_run-in_split_0.35rps.csv',
])
# tests_split_pccf.add_test_moment('after run-in bad', [
#     # 'test_data/2024-07-15__15-39-03_speedramp_split runin_120s.csv',  #bad data
#     'test_data/2024-07-15__16-49-37_speedramp_split runin_120s.csv',  # also bad data
#     'test_data/2024-07-15__15-46-08__torqueramp__split runin1.csv',
#     'test_data/2024-07-15__15-50-46__torqueramp__split runin5.csv',
#     'test_data/2024-07-15__15-56-24__torqueramp__split runin6.csv',
# ])
# tests_split_pccf.add_test_moment('after run-in', [
#     'test_data/2024-07-16__15-38-03_speedramp_split_pccf runin_120s.csv',
#     'test_data/2024-07-16__15-52-19__torqueramp__split_pccf runin1.csv',     #### started to lock up 
#     '',
#     '',
# ])

# reassembled making sure all preload screw set equally. motor recalibrated so changed angles
tests_split_pccf.add_test_moment('after run-in (and reassembled)', [
    'test_data/2024-07-17__13-23-30_speedramp_split_pccf runin reassembly_120s.csv',
    'test_data/2024-07-17__13-32-02__torqueramp__split reas1.csv',
    'test_data/2024-07-17__13-41-31__torqueramp__split reas6.csv',
    'test_data/2024-07-17__13-36-10__torqueramp__split reas5.csv',
])
tests_split_pccf.add_test_moment('preload increase 1', [
    'test_data/2024-07-17__13-52-38_speedramp_split 1pre_120s.csv',
    'test_data/2024-07-17__13-57-05__torqueramp__split 1pre1.csv',
    'test_data/2024-07-17__14-07-11__torqueramp__split 1pre5.csv',
    'test_data/2024-07-17__14-12-54__torqueramp__split 1pre6.csv',
])
tests_split_pccf.add_test_moment('preload increase 2', [
    'test_data/2024-07-17__14-20-20_speedramp_split 2pre_120s.csv',
    'test_data/2024-07-17__14-25-16__torqueramp__split 2pre1.csv',
    'test_data/2024-07-17__14-30-20__torqueramp__split 2pre5.csv',
    'test_data/2024-07-17__14-35-53__torqueramp__2pre6.csv',
])
tests_split_pccf.add_test_moment('preload increase 3', [
    'test_data/2024-07-17__14-48-51_speedramp_split 3pre_120s.csv',
    'test_data/2024-07-17__14-55-39__torqueramp__split 3pre1.csv',
    'test_data/2024-07-17__15-04-06__torqueramp__split 3pre5.csv',
    'test_data/2024-07-17__15-14-30__torqueramp__split 3pre6.csv',
])
loaded test_data/2024-07-15__14-17-32__torqueramp__split init1.csv.	 Test postion: -9.98 deg
loaded test_data/2024-07-15__14-26-05__torqueramp__split init5.csv.	 Test postion:  3.55 deg
loaded test_data/2024-07-15__14-35-07__torqueramp__split init6.csv.	 Test postion: -13.53 deg
loaded test_data/2024-07-15__14-09-03_speedramp_split init_120s.csv.
loaded 1 run-in tests, measured time: 0 days 00:19:03.936562800
loaded test_data/2024-07-17__13-32-02__torqueramp__split reas1.csv.	 Test postion: -10.25 deg
loaded test_data/2024-07-17__13-41-31__torqueramp__split reas6.csv.	 Test postion: 13.32 deg
loaded test_data/2024-07-17__13-36-10__torqueramp__split reas5.csv.	 Test postion:  3.64 deg
loaded test_data/2024-07-17__13-23-30_speedramp_split_pccf runin reassembly_120s.csv.
loaded test_data/2024-07-17__13-57-05__torqueramp__split 1pre1.csv.	 Test postion: -10.39 deg
loaded test_data/2024-07-17__14-07-11__torqueramp__split 1pre5.csv.	 Test postion:  3.69 deg
loaded test_data/2024-07-17__14-12-54__torqueramp__split 1pre6.csv.	 Test postion: 13.59 deg
loaded test_data/2024-07-17__13-52-38_speedramp_split 1pre_120s.csv.
loaded test_data/2024-07-17__14-25-16__torqueramp__split 2pre1.csv.	 Test postion: -10.07 deg
loaded test_data/2024-07-17__14-30-20__torqueramp__split 2pre5.csv.	 Test postion:  3.44 deg
loaded test_data/2024-07-17__14-35-53__torqueramp__2pre6.csv.	 Test postion: -13.55 deg
loaded test_data/2024-07-17__14-20-20_speedramp_split 2pre_120s.csv.
loaded test_data/2024-07-17__14-55-39__torqueramp__split 3pre1.csv.	 Test postion: -10.68 deg
loaded test_data/2024-07-17__15-04-06__torqueramp__split 3pre5.csv.	 Test postion:  2.93 deg
loaded test_data/2024-07-17__15-14-30__torqueramp__split 3pre6.csv.	 Test postion: -13.54 deg
loaded test_data/2024-07-17__14-48-51_speedramp_split 3pre_120s.csv.
In [ ]:
tests_base_910 = actuator_test_data('Baseline (Alloy 910)')
tests_base_910.add_test_moment('initial - unreamed', [
    # 'test_data/2024-07-15__16-28-49_speedramp_base910 unreamed init_120s.csv',
    'test_data/2024-07-15__16-56-07_speedramp_base910_unr init_120s.csv', 
    # 'test_data/2024-07-16__10-52-10__torqueramp__base910_unr init1.csv', 
    'test_data/2024-07-16__10-53-56__torqueramp__base910_unr init1.csv', 
    'test_data/2024-07-16__11-00-31__torqueramp__base910_unr init5.csv', 
    'test_data/2024-07-16__11-05-14__torqueramp__base910_unr init6.csv', 
])
tests_base_910.add_runin_tests([
    'test_data/2024-07-16__11-14-02_run-in_base910_unr_0.35rps.csv',
])
tests_base_910.add_test_moment('after run-in warm', [
    'test_data/2024-07-16__12-16-46_speedramp_base910_unr runin_120s.csv',
    'test_data/2024-07-16__11-55-30__torqueramp__base910_unr runin1.csv',
    'test_data/2024-07-16__12-03-12__torqueramp__base910_unr runin5.csv',
    'test_data/2024-07-16__12-11-39__torqueramp__base910_unr runin6.csv',
])
tests_base_910.add_test_moment('after run-in cold', [
    'test_data/2024-07-16__15-45-29_speedramp_base910_unr cold_120s.csv',
    'test_data/2024-07-16__14-23-33__torqueramp__base910_unr cold6.csv', 
    'test_data/2024-07-16__14-12-42__torqueramp__base910_unr cold5.csv',
    'test_data/2024-07-16__13-59-43__torqueramp__base910_unr cold1.csv',
])
tests_base_910.add_test_moment('after reaming output holes', [
    'test_data/2024-07-17__12-17-34_speedramp_base910_reamed_120s.csv',
    'test_data/2024-07-17__12-24-38__torqueramp__base910 reamed1.csv',
    'test_data/2024-07-17__12-40-35__torqueramp__base910 reamed5.csv',
    'test_data/2024-07-17__12-45-13__torqueramp__base910 reamed6.csv',
])
loaded test_data/2024-07-16__10-53-56__torqueramp__base910_unr init1.csv.	 Test postion:  9.01 deg
loaded test_data/2024-07-16__11-00-31__torqueramp__base910_unr init5.csv.	 Test postion: -4.81 deg
loaded test_data/2024-07-16__11-05-14__torqueramp__base910_unr init6.csv.	 Test postion:  5.32 deg
loaded test_data/2024-07-15__16-56-07_speedramp_base910_unr init_120s.csv.
loaded 1 run-in tests, measured time: 0 days 00:31:19.833365400
loaded test_data/2024-07-16__11-55-30__torqueramp__base910_unr runin1.csv.	 Test postion:  9.55 deg
loaded test_data/2024-07-16__12-03-12__torqueramp__base910_unr runin5.csv.	 Test postion: -4.07 deg
loaded test_data/2024-07-16__12-11-39__torqueramp__base910_unr runin6.csv.	 Test postion:  4.95 deg
loaded test_data/2024-07-16__12-16-46_speedramp_base910_unr runin_120s.csv.
loaded test_data/2024-07-16__14-23-33__torqueramp__base910_unr cold6.csv.	 Test postion:  4.78 deg
loaded test_data/2024-07-16__14-12-42__torqueramp__base910_unr cold5.csv.	 Test postion: -5.37 deg
loaded test_data/2024-07-16__13-59-43__torqueramp__base910_unr cold1.csv.	 Test postion:  8.30 deg
loaded test_data/2024-07-16__15-45-29_speedramp_base910_unr cold_120s.csv.
loaded test_data/2024-07-17__12-24-38__torqueramp__base910 reamed1.csv.	 Test postion: -1.83 deg
loaded test_data/2024-07-17__12-40-35__torqueramp__base910 reamed5.csv.	 Test postion: 12.20 deg
loaded test_data/2024-07-17__12-45-13__torqueramp__base910 reamed6.csv.	 Test postion: -5.26 deg
loaded test_data/2024-07-17__12-17-34_speedramp_base910_reamed_120s.csv.
In [ ]:
tests_base_onyx = actuator_test_data('Baseline (Onyx)')
tests_base_onyx.add_test_moment('initial', [
    'test_data/2024-07-17__15-37-53_run-in_base-onyx_0.35rps.csv',
    'test_data/2024-07-17__15-49-43__torqueramp__base_onyx init1.csv',
    'test_data/2024-07-17__15-54-23__torqueramp__base_onyx init5.csv',
    'test_data/2024-07-17__15-58-39__torqueramp__base_onyx init6.csv'
])
tests_base_onyx.add_runin_tests([
    'test_data/2024-07-17__16-00-53_run-in_base_onyx_0.35rps.csv',
])
tests_base_onyx.add_test_moment('after run-in', [
    'test_data/2024-07-18__10-35-38_speedramp_base_onyx runin_120s.csv',
    'test_data/2024-07-18__10-58-26__torqueramp__base_onyx runin1.csv',
    'test_data/2024-07-18__11-02-28__torqueramp__base_onyx runin5.csv',
    'test_data/2024-07-18__11-17-26__torqueramp__base_onyx runin6.csv',
])

tests_base_onyx.describe()
tests_base_onyx.runin_tests.plot(y=['Motor Torque [Nm]', 'Averaged Torque [Nm]'], secondary_y=['Motor Temperature [c]', 'Controller Temperature'], figsize=(10, 5))
tests_base_onyx.runin_tests
loaded test_data/2024-07-17__15-49-43__torqueramp__base_onyx init1.csv.	 Test postion: -1.46 deg
loaded test_data/2024-07-17__15-54-23__torqueramp__base_onyx init5.csv.	 Test postion: 12.40 deg
loaded test_data/2024-07-17__15-58-39__torqueramp__base_onyx init6.csv.	 Test postion: -4.90 deg
loaded 1 run-in tests, measured time: 0 days 01:20:49.309733900
loaded test_data/2024-07-18__10-58-26__torqueramp__base_onyx runin1.csv.	 Test postion: -1.52 deg
loaded test_data/2024-07-18__11-02-28__torqueramp__base_onyx runin5.csv.	 Test postion: 11.76 deg
loaded test_data/2024-07-18__11-17-26__torqueramp__base_onyx runin6.csv.	 Test postion: -5.05 deg
loaded test_data/2024-07-18__10-35-38_speedramp_base_onyx runin_120s.csv.
Configuration: Baseline (Onyx)
Speed ramps: ['after run-in']
Torque ramps:
  initial: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  after run-in: 4 ramps (dict_keys([0, 1, 2, 'combined']))
Run-in tests: 1 tests, total time: 0 days 01:20:49.309733900
Out[ ]:
Motor Torque [Nm] Averaged Torque [Nm] Motor Temperature [c] Controller Temperature [c] test number
Time [s]
0 days 00:00:00 0.000000 NaN 34.225269 36.0 0
0 days 00:00:00.002160900 0.000000 NaN 34.196332 36.0 0
0 days 00:00:00.003774900 0.000000 NaN 34.152925 36.0 0
0 days 00:00:00.005972300 0.000000 NaN 34.152925 35.0 0
0 days 00:00:00.008001200 0.000000 NaN 34.225269 36.0 0
... ... ... ... ... ...
0 days 01:20:49.301132800 3.831202 NaN 52.241051 52.0 0
0 days 01:20:49.303264400 2.654474 NaN 52.171503 52.0 0
0 days 01:20:49.305288400 3.511441 NaN 52.345370 52.0 0
0 days 01:20:49.307331800 1.397620 NaN 52.275822 52.0 0
0 days 01:20:49.309733900 3.643125 NaN 52.380141 52.0 0

2347077 rows × 5 columns

No description has been provided for this image
In [ ]:
tests_split_onyx = actuator_test_data('Split Pinwheel (Onyx)')
tests_split_onyx.add_test_moment('initial', [
    'test_data/2024-07-18__12-04-16_speedramp_split_onyx init_120s.csv',
    'test_data/2024-07-18__12-13-03__torqueramp__split_onyx init1.csv',
    'test_data/2024-07-18__12-22-04__torqueramp__split_onyx init5.csv',
    'test_data/2024-07-18__12-26-01__torqueramp__split_onyx init6.csv',
])
tests_split_onyx.add_runin_tests([
    'test_data/2024-07-18__12-32-09_run-in_split_onyx_0.35rps.csv',
])
tests_split_onyx.add_test_moment('after run-in', [
    'test_data/2024-07-18__16-21-56_speedramp_split_onyx runin_120s.csv',
    'test_data/2024-07-18__16-28-57__torqueramp__split_onyx runin1.csv',
    'test_data/2024-07-18__16-32-24__torqueramp__split_onyx runin5.csv',
    'test_data/2024-07-18__16-49-32__torqueramp__split_onyx runin6.csv',
])
tests_split_onyx.add_test_moment('preload increase 1', [
    'test_data/2024-07-18__16-54-19_speedramp_split_onyx 1pre_120s.csv',
    'test_data/2024-07-18__16-58-28__torqueramp__split_onyx 1pre1.csv',
    'test_data/2024-07-18__17-03-34__torqueramp__split_onyx 1pre5.csv',
    'test_data/2024-07-18__17-08-06__torqueramp__split_onyx 1pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 2', [
    # 'test_data/2024-07-18__17-13-19_speedramp_split_onyx 2pre_120s.csv',
    'test_data/2024-07-18__17-16-14_speedramp_split_onyx 2pre redo_120s.csv',
    'test_data/2024-07-18__17-20-15__torqueramp__split_onyx 2pre1.csv',
    'test_data/2024-07-18__17-23-41__torqueramp__split_onyx 2pre5.csv',
    'test_data/2024-07-18__17-26-47__torqueramp__split_onyx 2pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 3', [
    'test_data/2024-07-18__17-32-11_speedramp_split_onyx 3pre_120s.csv',
    'test_data/2024-07-18__17-36-03__torqueramp__split_onyx 3pre1.csv',
    'test_data/2024-07-18__17-40-43__torqueramp__split_onyx 3pre5.csv',
    'test_data/2024-07-18__17-45-38__torqueramp__split_onyx 3pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 4', [
    'test_data/2024-07-18__17-54-06_speedramp_split_onyx 4pre_120s.csv',
    'test_data/2024-07-18__18-00-07__torqueramp__split_onyx 4pre1.csv',
    'test_data/2024-07-18__18-03-49__torqueramp__split_onyx 4pre5.csv',
    'test_data/2024-07-18__18-06-57__torqueramp__split_onyx 4pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 5', [
    'test_data/2024-07-18__18-11-55_speedramp_split_onyx 5pre_120s.csv',
    'test_data/2024-07-18__18-15-26__torqueramp__split_onyx 5pre1.csv',
    'test_data/2024-07-18__18-18-30__torqueramp__split_onyx 5pre5.csv',
    'test_data/2024-07-18__18-21-33__torqueramp__split_onyx 5pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 6', [
    'test_data/2024-07-18__18-26-39_speedramp_split_onyx 6pre_120s.csv',
    'test_data/2024-07-18__18-30-11__torqueramp__split_onyx 6pre1.csv',
    'test_data/2024-07-18__18-33-20__torqueramp__split_onyx 6pre5.csv',
    'test_data/2024-07-18__18-36-30__torqueramp__split_onyx 6pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 7', [
    'test_data/2024-07-19__11-14-16_speedramp_split_onyx 7pre_120s.csv',
    'test_data/2024-07-19__11-18-58__torqueramp__split_onyx 7pre1.csv',
    'test_data/2024-07-19__11-22-18__torqueramp__split_onyx 7pre5.csv',
    'test_data/2024-07-19__11-25-41__torqueramp__split_onyx 7pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 8', [
    'test_data/2024-07-19__11-30-13_speedramp_split_onyx 8pre_120s.csv',
    'test_data/2024-07-19__11-35-25__torqueramp__split_onyx 8pre1.csv',
    'test_data/2024-07-19__11-38-44__torqueramp__split_onyx 8pre5.csv',
    'test_data/2024-07-19__11-41-55__torqueramp__split_onyx 8pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 9', [
    'test_data/2024-07-19__11-48-19_speedramp_split_onyx 9pre_120s.csv',
    'test_data/2024-07-19__11-52-46__torqueramp__split_onyx 9pre1.csv',
    'test_data/2024-07-19__11-56-19__torqueramp__split_onyx 9pre5.csv',
    'test_data/2024-07-19__11-59-31__torqueramp__split_onyx 9pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 10', [
    'test_data/2024-07-19__12-05-03_speedramp_split_onyx 10pre_120s.csv',
    'test_data/2024-07-19__12-13-32__torqueramp__split_onyx 10pre1.csv',
    'test_data/2024-07-19__12-17-03__torqueramp__split_onyx 10pre5.csv',
    'test_data/2024-07-19__12-10-03__torqueramp__split_onyx 10pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 11', [
    'test_data/2024-07-19__12-21-39_speedramp_split_onyx 11pre_120s.csv',
    'test_data/2024-07-19__12-25-42__torqueramp__split_onyx 11pre1.csv',
    'test_data/2024-07-19__12-30-41__torqueramp__split_onyx 11pre5.csv',
    'test_data/2024-07-19__12-36-11__torqueramp__split_onyx 11pre6.csv',
])
tests_split_onyx.add_test_moment('preload increase 12', [
    'test_data/2024-07-19__12-42-30_speedramp_split_onyx 12pre_120s.csv',
    'test_data/2024-07-19__12-45-43__torqueramp__split_onyx 12pre1.csv',
    'test_data/2024-07-19__12-49-55__torqueramp__split_onyx 12pre5.csv',
    'test_data/2024-07-19__12-54-36__torqueramp__split_onyx 12pre6.csv',
])

tests_split_onyx.describe()
loaded test_data/2024-07-18__12-13-03__torqueramp__split_onyx init1.csv.	 Test postion: -1.95 deg
loaded test_data/2024-07-18__12-22-04__torqueramp__split_onyx init5.csv.	 Test postion: 11.95 deg
loaded test_data/2024-07-18__12-26-01__torqueramp__split_onyx init6.csv.	 Test postion: -5.83 deg
loaded test_data/2024-07-18__12-04-16_speedramp_split_onyx init_120s.csv.
loaded 1 run-in tests, measured time: 0 days 01:28:14.930357600
loaded test_data/2024-07-18__16-28-57__torqueramp__split_onyx runin1.csv.	 Test postion: -1.50 deg
loaded test_data/2024-07-18__16-32-24__torqueramp__split_onyx runin5.csv.	 Test postion: 11.79 deg
loaded test_data/2024-07-18__16-49-32__torqueramp__split_onyx runin6.csv.	 Test postion: -5.66 deg
loaded test_data/2024-07-18__16-21-56_speedramp_split_onyx runin_120s.csv.
loaded test_data/2024-07-18__16-58-28__torqueramp__split_onyx 1pre1.csv.	 Test postion: -3.02 deg
loaded test_data/2024-07-18__17-03-34__torqueramp__split_onyx 1pre5.csv.	 Test postion: 11.13 deg
loaded test_data/2024-07-18__17-08-06__torqueramp__split_onyx 1pre6.csv.	 Test postion: -6.27 deg
loaded test_data/2024-07-18__16-54-19_speedramp_split_onyx 1pre_120s.csv.
loaded test_data/2024-07-18__17-20-15__torqueramp__split_onyx 2pre1.csv.	 Test postion: -3.02 deg
loaded test_data/2024-07-18__17-23-41__torqueramp__split_onyx 2pre5.csv.	 Test postion: 11.39 deg
loaded test_data/2024-07-18__17-26-47__torqueramp__split_onyx 2pre6.csv.	 Test postion: -6.03 deg
loaded test_data/2024-07-18__17-16-14_speedramp_split_onyx 2pre redo_120s.csv.
loaded test_data/2024-07-18__17-36-03__torqueramp__split_onyx 3pre1.csv.	 Test postion: -2.52 deg
loaded test_data/2024-07-18__17-40-43__torqueramp__split_onyx 3pre5.csv.	 Test postion: 11.32 deg
loaded test_data/2024-07-18__17-45-38__torqueramp__split_onyx 3pre6.csv.	 Test postion: -6.22 deg
loaded test_data/2024-07-18__17-32-11_speedramp_split_onyx 3pre_120s.csv.
loaded test_data/2024-07-18__18-00-07__torqueramp__split_onyx 4pre1.csv.	 Test postion: -2.38 deg
loaded test_data/2024-07-18__18-03-49__torqueramp__split_onyx 4pre5.csv.	 Test postion: 11.57 deg
loaded test_data/2024-07-18__18-06-57__torqueramp__split_onyx 4pre6.csv.	 Test postion: -6.01 deg
loaded test_data/2024-07-18__17-54-06_speedramp_split_onyx 4pre_120s.csv.
loaded test_data/2024-07-18__18-15-26__torqueramp__split_onyx 5pre1.csv.	 Test postion: -2.26 deg
loaded test_data/2024-07-18__18-18-30__torqueramp__split_onyx 5pre5.csv.	 Test postion: 11.32 deg
loaded test_data/2024-07-18__18-21-33__torqueramp__split_onyx 5pre6.csv.	 Test postion: -6.00 deg
loaded test_data/2024-07-18__18-11-55_speedramp_split_onyx 5pre_120s.csv.
loaded test_data/2024-07-18__18-30-11__torqueramp__split_onyx 6pre1.csv.	 Test postion: -2.32 deg
loaded test_data/2024-07-18__18-33-20__torqueramp__split_onyx 6pre5.csv.	 Test postion: 10.88 deg
loaded test_data/2024-07-18__18-36-30__torqueramp__split_onyx 6pre6.csv.	 Test postion: -6.38 deg
loaded test_data/2024-07-18__18-26-39_speedramp_split_onyx 6pre_120s.csv.
loaded test_data/2024-07-19__11-18-58__torqueramp__split_onyx 7pre1.csv.	 Test postion: -3.49 deg
loaded test_data/2024-07-19__11-22-18__torqueramp__split_onyx 7pre5.csv.	 Test postion: 10.33 deg
loaded test_data/2024-07-19__11-25-41__torqueramp__split_onyx 7pre6.csv.	 Test postion: -7.00 deg
loaded test_data/2024-07-19__11-14-16_speedramp_split_onyx 7pre_120s.csv.
loaded test_data/2024-07-19__11-35-25__torqueramp__split_onyx 8pre1.csv.	 Test postion: -2.98 deg
loaded test_data/2024-07-19__11-38-44__torqueramp__split_onyx 8pre5.csv.	 Test postion: 11.01 deg
loaded test_data/2024-07-19__11-41-55__torqueramp__split_onyx 8pre6.csv.	 Test postion: -6.76 deg
loaded test_data/2024-07-19__11-30-13_speedramp_split_onyx 8pre_120s.csv.
loaded test_data/2024-07-19__11-52-46__torqueramp__split_onyx 9pre1.csv.	 Test postion: -2.31 deg
loaded test_data/2024-07-19__11-56-19__torqueramp__split_onyx 9pre5.csv.	 Test postion: 10.71 deg
loaded test_data/2024-07-19__11-59-31__torqueramp__split_onyx 9pre6.csv.	 Test postion: -6.39 deg
loaded test_data/2024-07-19__11-48-19_speedramp_split_onyx 9pre_120s.csv.
loaded test_data/2024-07-19__12-13-32__torqueramp__split_onyx 10pre1.csv.	 Test postion: -2.70 deg
loaded test_data/2024-07-19__12-17-03__torqueramp__split_onyx 10pre5.csv.	 Test postion: 11.25 deg
loaded test_data/2024-07-19__12-10-03__torqueramp__split_onyx 10pre6.csv.	 Test postion: -6.29 deg
loaded test_data/2024-07-19__12-05-03_speedramp_split_onyx 10pre_120s.csv.
loaded test_data/2024-07-19__12-25-42__torqueramp__split_onyx 11pre1.csv.	 Test postion: -2.62 deg
loaded test_data/2024-07-19__12-30-41__torqueramp__split_onyx 11pre5.csv.	 Test postion: 11.69 deg
loaded test_data/2024-07-19__12-36-11__torqueramp__split_onyx 11pre6.csv.	 Test postion: -6.63 deg
loaded test_data/2024-07-19__12-21-39_speedramp_split_onyx 11pre_120s.csv.
loaded test_data/2024-07-19__12-45-43__torqueramp__split_onyx 12pre1.csv.	 Test postion: -3.15 deg
loaded test_data/2024-07-19__12-49-55__torqueramp__split_onyx 12pre5.csv.	 Test postion: 10.71 deg
loaded test_data/2024-07-19__12-54-36__torqueramp__split_onyx 12pre6.csv.	 Test postion: -6.73 deg
loaded test_data/2024-07-19__12-42-30_speedramp_split_onyx 12pre_120s.csv.
Configuration: Split Pinwheel (Onyx)
Speed ramps: ['initial', 'after run-in', 'preload increase 1', 'preload increase 2', 'preload increase 3', 'preload increase 4', 'preload increase 5', 'preload increase 6', 'preload increase 7', 'preload increase 8', 'preload increase 9', 'preload increase 10', 'preload increase 11', 'preload increase 12']
Torque ramps:
  initial: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  after run-in: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 1: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 2: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 3: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 4: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 5: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 6: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 7: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 8: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 9: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 10: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 11: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 12: 4 ramps (dict_keys([0, 1, 2, 'combined']))
Run-in tests: 1 tests, total time: 0 days 01:28:14.930357600
In [ ]:
tests_conic_onyx = actuator_test_data('Conic Disk (Onyx)')
tests_conic_onyx.add_test_moment('initial', [
    # 'test_data/2024-07-18__14-16-00_speedramp_cone_onyx init_120s.csv',
    'test_data/2024-07-18__14-18-36_speedramp_conic_onyx init_120s.csv',
    'test_data/2024-07-18__14-28-32__torqueramp__conic_onyx init1.csv',
    'test_data/2024-07-18__14-38-06__torqueramp__conic_onyx init5.csv',
    'test_data/2024-07-18__14-43-54__torqueramp__conic_onyx init6.csv',
])
tests_conic_onyx.add_runin_tests([
    'test_data/2024-07-18__14-46-11_run-in_conic_onyx_0.35rps.csv',
])
tests_conic_onyx.add_test_moment('after run-in', [
    'test_data/2024-07-19__13-01-08_speedramp_conic_onyx runin_120s.csv',
    # 'test_data/2024-07-19__13-05-35__torqueramp__conic_onyx runin1.csv',
    'test_data/2024-07-19__13-07-36__torqueramp__conic_onyx runin1.csv',
    'test_data/2024-07-19__13-10-53__torqueramp__conic_onyx runin5.csv',
    'test_data/2024-07-19__13-15-33__torqueramp__conic_onyx runin6.csv',
])
tests_conic_onyx.add_test_moment('preload increase 1', [
    'test_data/2024-07-19__13-22-07_speedramp_conic_onyx 1pre_120s.csv',
    'test_data/2024-07-19__13-27-30__torqueramp__conic_onyx 1pre1.csv',
    'test_data/2024-07-19__13-30-53__torqueramp__conic_onyx 1pre1.csv',
    'test_data/2024-07-19__13-37-48__torqueramp__conic_onyx 1pre5.csv',
    'test_data/2024-07-19__13-43-25__torqueramp__conic_onyx 1pre6.csv',
])
tests_conic_onyx.add_test_moment('preload increase 2', [
    'test_data/2024-07-19__13-49-49_speedramp_conic_onyx 2pre_120s.csv',
    'test_data/2024-07-19__13-53-23__torqueramp__conic_onyx 2pre1.csv',
    'test_data/2024-07-19__13-57-00__torqueramp__conic_onyx 2pre5.csv',
    'test_data/2024-07-19__14-00-00__torqueramp__conic_onyx 2pre6.csv',
])
tests_conic_onyx.add_test_moment('preload increase 3', [
    'test_data/2024-07-19__14-06-46_speedramp_conic_onyx 3pre_120s.csv',
    'test_data/2024-07-19__14-10-07__torqueramp__conic_onyx 3pre1.csv',
    'test_data/2024-07-19__14-13-41__torqueramp__conic_onyx 3pre5.csv',
    'test_data/2024-07-19__14-18-09__torqueramp__conic_onyx 3pre6.csv',
])
tests_conic_onyx.add_test_moment('preload increase 4', [
    'test_data/2024-07-19__14-23-33_speedramp_conic_onyx 4pre_120s.csv',
    'test_data/2024-07-19__14-28-09__torqueramp__conic_onyx 4pre1.csv',
    'test_data/2024-07-19__14-36-36__torqueramp__conic_onyx 4pre5.csv',
    'test_data/2024-07-19__14-40-25__torqueramp__conic_onyx 4pre6.csv',
])
tests_conic_onyx.add_test_moment('preload increase 5', [
    'test_data/2024-07-19__14-48-41_speedramp_conic_onyx 5pre_120s.csv',
    'test_data/2024-07-19__14-53-13__torqueramp__conic_onyx 5pre1.csv',
    'test_data/2024-07-19__14-56-49__torqueramp__conic_onyx 5pre5.csv',

    'test_data/2024-07-19__15-00-38__torqueramp__conic_onyx 5pre6.csv',
])


tests_conic_onyx.describe()
loaded test_data/2024-07-18__14-28-32__torqueramp__conic_onyx init1.csv.	 Test postion:  2.22 deg
loaded test_data/2024-07-18__14-38-06__torqueramp__conic_onyx init5.csv.	 Test postion: -11.06 deg
loaded test_data/2024-07-18__14-43-54__torqueramp__conic_onyx init6.csv.	 Test postion: -0.69 deg
loaded test_data/2024-07-18__14-18-36_speedramp_conic_onyx init_120s.csv.
loaded 1 run-in tests, measured time: 0 days 01:31:50.694483500
loaded test_data/2024-07-19__13-07-36__torqueramp__conic_onyx runin1.csv.	 Test postion:  1.37 deg
loaded test_data/2024-07-19__13-10-53__torqueramp__conic_onyx runin5.csv.	 Test postion: -11.56 deg
loaded test_data/2024-07-19__13-15-33__torqueramp__conic_onyx runin6.csv.	 Test postion: -0.88 deg
loaded test_data/2024-07-19__13-01-08_speedramp_conic_onyx runin_120s.csv.
loaded test_data/2024-07-19__13-27-30__torqueramp__conic_onyx 1pre1.csv.	 Test postion:  2.31 deg
loaded test_data/2024-07-19__13-30-53__torqueramp__conic_onyx 1pre1.csv.	 Test postion:  1.55 deg
loaded test_data/2024-07-19__13-37-48__torqueramp__conic_onyx 1pre5.csv.	 Test postion: -10.79 deg
loaded test_data/2024-07-19__13-43-25__torqueramp__conic_onyx 1pre6.csv.	 Test postion: -1.26 deg
loaded test_data/2024-07-19__13-22-07_speedramp_conic_onyx 1pre_120s.csv.
loaded test_data/2024-07-19__13-53-23__torqueramp__conic_onyx 2pre1.csv.	 Test postion:  1.70 deg
loaded test_data/2024-07-19__13-57-00__torqueramp__conic_onyx 2pre5.csv.	 Test postion: -11.89 deg
loaded test_data/2024-07-19__14-00-00__torqueramp__conic_onyx 2pre6.csv.	 Test postion: -1.47 deg
loaded test_data/2024-07-19__13-49-49_speedramp_conic_onyx 2pre_120s.csv.
loaded test_data/2024-07-19__14-10-07__torqueramp__conic_onyx 3pre1.csv.	 Test postion:  2.20 deg
loaded test_data/2024-07-19__14-13-41__torqueramp__conic_onyx 3pre5.csv.	 Test postion: -11.47 deg
loaded test_data/2024-07-19__14-18-09__torqueramp__conic_onyx 3pre6.csv.	 Test postion: -1.43 deg
loaded test_data/2024-07-19__14-06-46_speedramp_conic_onyx 3pre_120s.csv.
loaded test_data/2024-07-19__14-28-09__torqueramp__conic_onyx 4pre1.csv.	 Test postion:  2.14 deg
loaded test_data/2024-07-19__14-36-36__torqueramp__conic_onyx 4pre5.csv.	 Test postion: -11.64 deg
loaded test_data/2024-07-19__14-40-25__torqueramp__conic_onyx 4pre6.csv.	 Test postion: -0.88 deg
loaded test_data/2024-07-19__14-23-33_speedramp_conic_onyx 4pre_120s.csv.
loaded test_data/2024-07-19__14-53-13__torqueramp__conic_onyx 5pre1.csv.	 Test postion:  1.49 deg
loaded test_data/2024-07-19__14-56-49__torqueramp__conic_onyx 5pre5.csv.	 Test postion: -11.74 deg
loaded test_data/2024-07-19__15-00-38__torqueramp__conic_onyx 5pre6.csv.	 Test postion: -1.87 deg
loaded test_data/2024-07-19__14-48-41_speedramp_conic_onyx 5pre_120s.csv.
Configuration: Conic Disk (Onyx)
Speed ramps: ['initial', 'after run-in', 'preload increase 1', 'preload increase 2', 'preload increase 3', 'preload increase 4', 'preload increase 5']
Torque ramps:
  initial: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  after run-in: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 1: 5 ramps (dict_keys([0, 1, 2, 3, 'combined']))
  preload increase 2: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 3: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 4: 4 ramps (dict_keys([0, 1, 2, 'combined']))
  preload increase 5: 4 ramps (dict_keys([0, 1, 2, 'combined']))
Run-in tests: 1 tests, total time: 0 days 01:31:50.694483500

data visualization¶

In [ ]:
## unused: tests_split_pccf_u,
actuators = [tests_base_onyx, tests_split_onyx, tests_conic_onyx, tests_base_910,  tests_base_pccf, tests_conic_pccf, tests_split_pccf,]

def estimate_play_and_stiffness(play_test, stiffness_test):
    def get_rising_slopes(df):
        # split data in to positive and negative slopes. remove the hysteresis part
        max_torque_idx = df['Desired Torque [Nm]'].idxmax()
        pos_slope = df.loc[:max_torque_idx]

        # find zero crossing of desired torque
        min_torque_idx = df['Desired Torque [Nm]'].idxmin()
        zero_torque_idx = df['Desired Torque [Nm]'][max_torque_idx:min_torque_idx].abs().idxmin()
        neg_slope = df.loc[zero_torque_idx:min_torque_idx]

        return pos_slope, neg_slope

    # estimate play
    play_pos_slope, play_neg_slope = get_rising_slopes(play_test)
    pos_play = play_pos_slope['Deflection [deg]'].iloc[0]
    neg_play = play_neg_slope['Deflection [deg]'].iloc[0]
    play = neg_play - pos_play
    # print(f'Play: {play} deg ({pos_play} pos, {neg_play} neg)')

    # estimate stiffness
    stiffness_pos_slope, stiffness_neg_slope = get_rising_slopes(stiffness_test)
    stiffness_pos_slope = stiffness_pos_slope[stiffness_pos_slope['Deflection [deg]'] > neg_play]
    stiffness_neg_slope = stiffness_neg_slope[stiffness_neg_slope['Deflection [deg]'] < pos_play]

    # do polyfit
    pos_stiffness, pos_offset = np.polyfit(stiffness_pos_slope['Motor Torque [Nm]'], stiffness_pos_slope['Deflection [deg]'], 1)
    neg_stiffness, neg_offset = np.polyfit(stiffness_neg_slope['Motor Torque [Nm]'], stiffness_neg_slope['Deflection [deg]'], 1)

    # print(f'Positive stiffness: {pos_stiffness} deg/Nm, offset: {pos_offset} deg')
    # print(f'Negative stiffness: {neg_stiffness} deg/Nm, offset: {neg_offset} deg')

    results = {
        'Play [deg]': play,
        'Stiffness [deg/Nm]': (pos_stiffness + neg_stiffness) / 2,
        'pos_stiffness': pos_stiffness,
        'neg_stiffness': neg_stiffness,
    }
    return results

def estimate_friction(df):
    MIN_SPEED = 0.05
    MAX_SPEED = 0.45
    
    pos_df = df[df['Motor Speed [rpm]'] > MIN_SPEED]
    neg_df = df[df['Motor Speed [rpm]'] < -MIN_SPEED]

    pos_df = pos_df[pos_df['Motor Speed [rpm]'] < MAX_SPEED]
    neg_df = neg_df[neg_df['Motor Speed [rpm]'] > -MAX_SPEED]



    pos_coulomb = pos_df['Motor Torque [Nm]'].mean()
    neg_coulomb = neg_df['Motor Torque [Nm]'].mean()
    coulomb = (pos_coulomb - neg_coulomb) / 2

    results = {
        'Coulomb Friction [Nm]': coulomb,
        'coulomb_neg': neg_coulomb,
        'coulomb_pos': pos_coulomb,
    }
    return results


# create resuls dataframe
results_df = pd.DataFrame()
for i, actuator in enumerate(actuators):
    results_dict = {}
    print(f'\nActuator: {actuator.configuration}')

    # itterate torque ramps
    for j, (name, ramps) in enumerate(actuator.torque_ramps.items()):
        print(f'  Test: {name}')
        for k, (play_test, stiffness_test) in ramps.items():       
            torque_results = estimate_play_and_stiffness(play_test, stiffness_test)
            results = {'actuator': actuator.configuration, 'moment': name, 'test_nr': k, **torque_results}
            results_dict[name] = {**results, **results_dict.get(name, {})}
            print(f'    Test {k:8}: \t', ',\t '.join([f'{k}:{v:7.3f}' for k, v in torque_results.items()]))

    # itterate speed ramps
    print(f'  Speed ramps')
    for j, (name, df) in enumerate(actuator.speed_ramps.items()):
        fric_results = estimate_friction(df)
        speed_results = {'actuator': actuator.configuration, 'test': name, **fric_results}
        results = {'actuator': actuator.configuration, 'moment': name, **speed_results}
        results_dict[name] = {**results, **results_dict.get(name, {})}
        print(f'    {name:20}: \t', ',\t '.join([f'{k}:{v:7.3f}' for k, v in fric_results.items()]))



    results_df = pd.concat([results_df, pd.DataFrame(results_dict).T])



################ plot friction bar plot
fig, ax = plt.subplots(1, 1, figsize=(10, 5))
ax.set_title('Friction models')

num_tests = sum([len(actuator.speed_ramps) for actuator in actuators])
num_bars = num_tests + len(actuators) - 1
bar_width = 0.8  # Adjust bar width for visibility within groups
bar_pos = num_bars
labels = []
colors = plt.cm.viridis(np.linspace(0, 1, len(actuators)))
for i, actuator in enumerate(actuators):
    for j, (name, df) in enumerate(actuator.speed_ramps.items()):
        fric_results = estimate_friction(df)

        ax.plot((-fric_results['coulomb_neg'], fric_results['coulomb_pos']), (bar_pos, bar_pos), color=colors[i], linewidth=6, alpha=0.7)
        ax.plot((fric_results['Coulomb Friction [Nm]'], fric_results['Coulomb Friction [Nm]']), (bar_pos-0.4, bar_pos+0.4), color=colors[i])
        # indicate positive/negative side
        ax.plot(fric_results['coulomb_pos'], bar_pos, '^', color='black', markersize=7)
        ax.plot(-fric_results['coulomb_neg'], bar_pos, 'v', color='black', markersize=7)

        bar_pos -= 1
        labels.append(name)
        
    if i < len(actuators) - 1:
        ax.axhline(bar_pos, color='gray', linewidth=0.8, linestyle='--')
        bar_pos -= 1
        labels.append('')

    results_df = pd.concat([results_df, pd.DataFrame(results_dict).T])

print(labels)
handles = [plt.Line2D([0], [0], color=colors[i], lw=4) for i in range(len(actuators))]
ax.legend(handles, [f'\\ld{{{actuator.configuration}}}' for actuator in actuators], title='Actuator', loc='upper right')
ax.set_yticks(np.arange(1, len(labels)+1))
ax.set_yticklabels(reversed(labels))
ax.set_xticks(np.arange(1.0, 12, 0.5))
ax.set_xlabel('Coulomb Friction [Nm]')

fig.tight_layout()
fig.savefig(f'figures/friction barplot.svg')
plt.show()


# plot torque-displacement for each actuator
for actuator in actuators:
    fig, axs = plt.subplots(1, 2, figsize=(14, 5))
    fig.suptitle(actuator.configuration)
    axs[0].set_title('Play tests')
    axs[1].set_title('Stiffness tests')
    axs[0].set_xlabel('Motor Torque [Nm]')
    axs[0].set_ylabel('Deflection [deg]')
    axs[1].set_xlabel('Motor Torque [Nm]')
    axs[1].set_ylabel('Deflection [deg]')

    colors = plt.cm.viridis(np.linspace(0, 1, len(actuator.torque_ramps)))
    for i, (name, ramps) in enumerate(actuator.torque_ramps.items()):
        (play_test_mean, stiffness_test_mean) = ramps['combined']

        axs[0].plot(play_test_mean['Motor Torque [Nm]'], play_test_mean['Deflection [deg]'], label=f'\\ld{{{name}}}', color=colors[i])
        axs[1].plot(stiffness_test_mean['Motor Torque [Nm]'], stiffness_test_mean['Deflection [deg]'], label=f'\\ld{{{name}}}', color=colors[i])

    axs[1].legend(loc='upper left')
    fig.tight_layout()

    fig.savefig(f'figures/torque-displacement of {actuator.configuration}.svg')
    plt.show()


# results_df
Actuator: Baseline (Onyx)
  Test: initial
    Test        0: 	 Play [deg]:  1.238,	 Stiffness [deg/Nm]:  0.185,	 pos_stiffness:  0.188,	 neg_stiffness:  0.181
    Test        1: 	 Play [deg]:  1.177,	 Stiffness [deg/Nm]:  0.163,	 pos_stiffness:  0.146,	 neg_stiffness:  0.179
    Test        2: 	 Play [deg]:  0.559,	 Stiffness [deg/Nm]:  0.159,	 pos_stiffness:  0.146,	 neg_stiffness:  0.172
    Test combined: 	 Play [deg]:  0.988,	 Stiffness [deg/Nm]:  0.169,	 pos_stiffness:  0.161,	 neg_stiffness:  0.177
  Test: after run-in
    Test        0: 	 Play [deg]:  1.558,	 Stiffness [deg/Nm]:  0.170,	 pos_stiffness:  0.171,	 neg_stiffness:  0.169
    Test        1: 	 Play [deg]:  1.694,	 Stiffness [deg/Nm]:  0.174,	 pos_stiffness:  0.161,	 neg_stiffness:  0.187
    Test        2: 	 Play [deg]:  1.090,	 Stiffness [deg/Nm]:  0.168,	 pos_stiffness:  0.161,	 neg_stiffness:  0.175
    Test combined: 	 Play [deg]:  1.444,	 Stiffness [deg/Nm]:  0.171,	 pos_stiffness:  0.165,	 neg_stiffness:  0.177
  Speed ramps
    after run-in        : 	 Coulomb Friction [Nm]:  2.672,	 coulomb_neg: -2.859,	 coulomb_pos:  2.485

Actuator: Split Pinwheel (Onyx)
  Test: initial
    Test        0: 	 Play [deg]:  0.895,	 Stiffness [deg/Nm]:  0.197,	 pos_stiffness:  0.192,	 neg_stiffness:  0.202
    Test        1: 	 Play [deg]:  0.260,	 Stiffness [deg/Nm]:  0.180,	 pos_stiffness:  0.199,	 neg_stiffness:  0.161
    Test        2: 	 Play [deg]:  0.276,	 Stiffness [deg/Nm]:  0.192,	 pos_stiffness:  0.202,	 neg_stiffness:  0.183
    Test combined: 	 Play [deg]:  0.476,	 Stiffness [deg/Nm]:  0.190,	 pos_stiffness:  0.198,	 neg_stiffness:  0.183
  Test: after run-in
    Test        0: 	 Play [deg]:  1.556,	 Stiffness [deg/Nm]:  0.185,	 pos_stiffness:  0.189,	 neg_stiffness:  0.181
    Test        1: 	 Play [deg]:  0.584,	 Stiffness [deg/Nm]:  0.184,	 pos_stiffness:  0.192,	 neg_stiffness:  0.177
    Test        2: 	 Play [deg]:  1.311,	 Stiffness [deg/Nm]:  0.191,	 pos_stiffness:  0.179,	 neg_stiffness:  0.202
    Test combined: 	 Play [deg]:  1.147,	 Stiffness [deg/Nm]:  0.187,	 pos_stiffness:  0.187,	 neg_stiffness:  0.187
  Test: preload increase 1
    Test        0: 	 Play [deg]:  1.545,	 Stiffness [deg/Nm]:  0.215,	 pos_stiffness:  0.216,	 neg_stiffness:  0.214
    Test        1: 	 Play [deg]:  1.357,	 Stiffness [deg/Nm]:  0.187,	 pos_stiffness:  0.197,	 neg_stiffness:  0.178
    Test        2: 	 Play [deg]:  0.415,	 Stiffness [deg/Nm]:  0.208,	 pos_stiffness:  0.206,	 neg_stiffness:  0.209
    Test combined: 	 Play [deg]:  1.105,	 Stiffness [deg/Nm]:  0.203,	 pos_stiffness:  0.205,	 neg_stiffness:  0.201
  Test: preload increase 2
    Test        0: 	 Play [deg]:  1.611,	 Stiffness [deg/Nm]:  0.237,	 pos_stiffness:  0.234,	 neg_stiffness:  0.240
    Test        1: 	 Play [deg]:  1.292,	 Stiffness [deg/Nm]:  0.225,	 pos_stiffness:  0.223,	 neg_stiffness:  0.227
    Test        2: 	 Play [deg]:  1.158,	 Stiffness [deg/Nm]:  0.208,	 pos_stiffness:  0.196,	 neg_stiffness:  0.219
    Test combined: 	 Play [deg]:  1.354,	 Stiffness [deg/Nm]:  0.223,	 pos_stiffness:  0.218,	 neg_stiffness:  0.229
  Test: preload increase 3
    Test        0: 	 Play [deg]:  0.765,	 Stiffness [deg/Nm]:  0.238,	 pos_stiffness:  0.235,	 neg_stiffness:  0.242
    Test        1: 	 Play [deg]:  1.174,	 Stiffness [deg/Nm]:  0.237,	 pos_stiffness:  0.242,	 neg_stiffness:  0.232
    Test        2: 	 Play [deg]:  0.468,	 Stiffness [deg/Nm]:  0.219,	 pos_stiffness:  0.206,	 neg_stiffness:  0.231
    Test combined: 	 Play [deg]:  0.802,	 Stiffness [deg/Nm]:  0.231,	 pos_stiffness:  0.227,	 neg_stiffness:  0.235
  Test: preload increase 4
    Test        0: 	 Play [deg]:  1.349,	 Stiffness [deg/Nm]:  0.219,	 pos_stiffness:  0.212,	 neg_stiffness:  0.226
    Test        1: 	 Play [deg]:  1.253,	 Stiffness [deg/Nm]:  0.212,	 pos_stiffness:  0.224,	 neg_stiffness:  0.199
    Test        2: 	 Play [deg]:  0.245,	 Stiffness [deg/Nm]:  0.218,	 pos_stiffness:  0.207,	 neg_stiffness:  0.229
    Test combined: 	 Play [deg]:  0.949,	 Stiffness [deg/Nm]:  0.217,	 pos_stiffness:  0.215,	 neg_stiffness:  0.219
  Test: preload increase 5
    Test        0: 	 Play [deg]:  0.292,	 Stiffness [deg/Nm]:  0.247,	 pos_stiffness:  0.261,	 neg_stiffness:  0.232
    Test        1: 	 Play [deg]:  1.009,	 Stiffness [deg/Nm]:  0.212,	 pos_stiffness:  0.226,	 neg_stiffness:  0.198
    Test        2: 	 Play [deg]:  0.241,	 Stiffness [deg/Nm]:  0.230,	 pos_stiffness:  0.219,	 neg_stiffness:  0.241
    Test combined: 	 Play [deg]:  0.513,	 Stiffness [deg/Nm]:  0.230,	 pos_stiffness:  0.235,	 neg_stiffness:  0.224
  Test: preload increase 6
    Test        0: 	 Play [deg]:  0.224,	 Stiffness [deg/Nm]:  0.287,	 pos_stiffness:  0.275,	 neg_stiffness:  0.299
    Test        1: 	 Play [deg]:  0.111,	 Stiffness [deg/Nm]:  0.264,	 pos_stiffness:  0.273,	 neg_stiffness:  0.256
    Test        2: 	 Play [deg]:  0.175,	 Stiffness [deg/Nm]:  0.260,	 pos_stiffness:  0.228,	 neg_stiffness:  0.291
    Test combined: 	 Play [deg]:  0.169,	 Stiffness [deg/Nm]:  0.270,	 pos_stiffness:  0.259,	 neg_stiffness:  0.281
  Test: preload increase 7
    Test        0: 	 Play [deg]:  0.241,	 Stiffness [deg/Nm]:  0.206,	 pos_stiffness:  0.231,	 neg_stiffness:  0.181
    Test        1: 	 Play [deg]:  0.362,	 Stiffness [deg/Nm]:  0.210,	 pos_stiffness:  0.233,	 neg_stiffness:  0.187
    Test        2: 	 Play [deg]:  1.186,	 Stiffness [deg/Nm]:  0.193,	 pos_stiffness:  0.192,	 neg_stiffness:  0.194
    Test combined: 	 Play [deg]:  0.596,	 Stiffness [deg/Nm]:  0.204,	 pos_stiffness:  0.219,	 neg_stiffness:  0.189
  Test: preload increase 8
    Test        0: 	 Play [deg]:  0.433,	 Stiffness [deg/Nm]:  0.288,	 pos_stiffness:  0.269,	 neg_stiffness:  0.307
    Test        1: 	 Play [deg]:  0.245,	 Stiffness [deg/Nm]:  0.242,	 pos_stiffness:  0.255,	 neg_stiffness:  0.229
    Test        2: 	 Play [deg]:  0.487,	 Stiffness [deg/Nm]:  0.189,	 pos_stiffness:  0.194,	 neg_stiffness:  0.184
    Test combined: 	 Play [deg]:  0.388,	 Stiffness [deg/Nm]:  0.240,	 pos_stiffness:  0.240,	 neg_stiffness:  0.240
  Test: preload increase 9
    Test        0: 	 Play [deg]:  0.239,	 Stiffness [deg/Nm]:  0.237,	 pos_stiffness:  0.233,	 neg_stiffness:  0.241
    Test        1: 	 Play [deg]:  0.376,	 Stiffness [deg/Nm]:  0.233,	 pos_stiffness:  0.248,	 neg_stiffness:  0.217
    Test        2: 	 Play [deg]:  0.433,	 Stiffness [deg/Nm]:  0.207,	 pos_stiffness:  0.195,	 neg_stiffness:  0.220
    Test combined: 	 Play [deg]:  0.345,	 Stiffness [deg/Nm]:  0.226,	 pos_stiffness:  0.224,	 neg_stiffness:  0.227
  Test: preload increase 10
    Test        0: 	 Play [deg]:  0.346,	 Stiffness [deg/Nm]:  0.271,	 pos_stiffness:  0.259,	 neg_stiffness:  0.283
    Test        1: 	 Play [deg]:  0.198,	 Stiffness [deg/Nm]:  0.259,	 pos_stiffness:  0.275,	 neg_stiffness:  0.242
    Test        2: 	 Play [deg]:  0.226,	 Stiffness [deg/Nm]:  0.233,	 pos_stiffness:  0.225,	 neg_stiffness:  0.240
    Test combined: 	 Play [deg]:  0.256,	 Stiffness [deg/Nm]:  0.255,	 pos_stiffness:  0.253,	 neg_stiffness:  0.257
  Test: preload increase 11
    Test        0: 	 Play [deg]:  0.225,	 Stiffness [deg/Nm]:  0.313,	 pos_stiffness:  0.298,	 neg_stiffness:  0.328
    Test        1: 	 Play [deg]:  0.208,	 Stiffness [deg/Nm]:  0.266,	 pos_stiffness:  0.274,	 neg_stiffness:  0.259
    Test        2: 	 Play [deg]:  0.360,	 Stiffness [deg/Nm]:  0.246,	 pos_stiffness:  0.239,	 neg_stiffness:  0.253
    Test combined: 	 Play [deg]:  0.263,	 Stiffness [deg/Nm]:  0.275,	 pos_stiffness:  0.270,	 neg_stiffness:  0.280
  Test: preload increase 12
    Test        0: 	 Play [deg]:  0.274,	 Stiffness [deg/Nm]:  0.269,	 pos_stiffness:  0.259,	 neg_stiffness:  0.279
    Test        1: 	 Play [deg]:  0.446,	 Stiffness [deg/Nm]:  0.236,	 pos_stiffness:  0.242,	 neg_stiffness:  0.230
    Test        2: 	 Play [deg]:  0.820,	 Stiffness [deg/Nm]:  0.238,	 pos_stiffness:  0.236,	 neg_stiffness:  0.241
    Test combined: 	 Play [deg]:  0.510,	 Stiffness [deg/Nm]:  0.250,	 pos_stiffness:  0.251,	 neg_stiffness:  0.250
  Speed ramps
    initial             : 	 Coulomb Friction [Nm]:  4.167,	 coulomb_neg: -4.084,	 coulomb_pos:  4.251
    after run-in        : 	 Coulomb Friction [Nm]:  2.896,	 coulomb_neg: -2.557,	 coulomb_pos:  3.236
    preload increase 1  : 	 Coulomb Friction [Nm]:  3.198,	 coulomb_neg: -2.722,	 coulomb_pos:  3.675
    preload increase 2  : 	 Coulomb Friction [Nm]:  3.000,	 coulomb_neg: -2.698,	 coulomb_pos:  3.302
    preload increase 3  : 	 Coulomb Friction [Nm]:  3.290,	 coulomb_neg: -2.963,	 coulomb_pos:  3.617
    preload increase 4  : 	 Coulomb Friction [Nm]:  3.642,	 coulomb_neg: -3.290,	 coulomb_pos:  3.993
    preload increase 5  : 	 Coulomb Friction [Nm]:  3.997,	 coulomb_neg: -3.640,	 coulomb_pos:  4.353
    preload increase 6  : 	 Coulomb Friction [Nm]:  4.407,	 coulomb_neg: -4.054,	 coulomb_pos:  4.760
    preload increase 7  : 	 Coulomb Friction [Nm]:  5.760,	 coulomb_neg: -5.251,	 coulomb_pos:  6.270
    preload increase 8  : 	 Coulomb Friction [Nm]:  5.701,	 coulomb_neg: -5.422,	 coulomb_pos:  5.980
    preload increase 9  : 	 Coulomb Friction [Nm]:  5.587,	 coulomb_neg: -5.324,	 coulomb_pos:  5.849
    preload increase 10 : 	 Coulomb Friction [Nm]:  5.415,	 coulomb_neg: -5.189,	 coulomb_pos:  5.642
    preload increase 11 : 	 Coulomb Friction [Nm]:  5.434,	 coulomb_neg: -5.187,	 coulomb_pos:  5.680
    preload increase 12 : 	 Coulomb Friction [Nm]:  5.508,	 coulomb_neg: -5.350,	 coulomb_pos:  5.667

Actuator: Conic Disk (Onyx)
  Test: initial
    Test        0: 	 Play [deg]:  0.720,	 Stiffness [deg/Nm]:  0.206,	 pos_stiffness:  0.180,	 neg_stiffness:  0.232
    Test        1: 	 Play [deg]:  0.888,	 Stiffness [deg/Nm]:  0.191,	 pos_stiffness:  0.183,	 neg_stiffness:  0.199
    Test        2: 	 Play [deg]:  0.762,	 Stiffness [deg/Nm]:  0.213,	 pos_stiffness:  0.180,	 neg_stiffness:  0.245
    Test combined: 	 Play [deg]:  0.788,	 Stiffness [deg/Nm]:  0.206,	 pos_stiffness:  0.181,	 neg_stiffness:  0.230
  Test: after run-in
    Test        0: 	 Play [deg]:  2.345,	 Stiffness [deg/Nm]:  0.187,	 pos_stiffness:  0.174,	 neg_stiffness:  0.201
    Test        1: 	 Play [deg]:  1.086,	 Stiffness [deg/Nm]:  0.177,	 pos_stiffness:  0.159,	 neg_stiffness:  0.195
    Test        2: 	 Play [deg]:  0.811,	 Stiffness [deg/Nm]:  0.191,	 pos_stiffness:  0.168,	 neg_stiffness:  0.214
    Test combined: 	 Play [deg]:  1.412,	 Stiffness [deg/Nm]:  0.188,	 pos_stiffness:  0.166,	 neg_stiffness:  0.210
  Test: preload increase 1
    Test        0: 	 Play [deg]:  1.252,	 Stiffness [deg/Nm]:  0.214,	 pos_stiffness:  0.206,	 neg_stiffness:  0.222
    Test        1: 	 Play [deg]:  1.777,	 Stiffness [deg/Nm]:  0.189,	 pos_stiffness:  0.171,	 neg_stiffness:  0.208
    Test        2: 	 Play [deg]:  0.750,	 Stiffness [deg/Nm]:  0.181,	 pos_stiffness:  0.165,	 neg_stiffness:  0.198
    Test        3: 	 Play [deg]:  0.606,	 Stiffness [deg/Nm]:  0.193,	 pos_stiffness:  0.169,	 neg_stiffness:  0.217
    Test combined: 	 Play [deg]:  1.094,	 Stiffness [deg/Nm]:  0.197,	 pos_stiffness:  0.177,	 neg_stiffness:  0.217
  Test: preload increase 2
    Test        0: 	 Play [deg]:  0.665,	 Stiffness [deg/Nm]:  0.196,	 pos_stiffness:  0.170,	 neg_stiffness:  0.222
    Test        1: 	 Play [deg]:  0.573,	 Stiffness [deg/Nm]:  0.186,	 pos_stiffness:  0.156,	 neg_stiffness:  0.216
    Test        2: 	 Play [deg]:  0.546,	 Stiffness [deg/Nm]:  0.180,	 pos_stiffness:  0.153,	 neg_stiffness:  0.208
    Test combined: 	 Play [deg]:  0.593,	 Stiffness [deg/Nm]:  0.188,	 pos_stiffness:  0.160,	 neg_stiffness:  0.216
  Test: preload increase 3
    Test        0: 	 Play [deg]:  0.663,	 Stiffness [deg/Nm]:  0.192,	 pos_stiffness:  0.175,	 neg_stiffness:  0.209
    Test        1: 	 Play [deg]:  0.705,	 Stiffness [deg/Nm]:  0.182,	 pos_stiffness:  0.156,	 neg_stiffness:  0.207
    Test        2: 	 Play [deg]:  0.609,	 Stiffness [deg/Nm]:  0.187,	 pos_stiffness:  0.165,	 neg_stiffness:  0.209
    Test combined: 	 Play [deg]:  0.658,	 Stiffness [deg/Nm]:  0.188,	 pos_stiffness:  0.167,	 neg_stiffness:  0.209
  Test: preload increase 4
    Test        0: 	 Play [deg]:  0.706,	 Stiffness [deg/Nm]:  0.191,	 pos_stiffness:  0.180,	 neg_stiffness:  0.202
    Test        1: 	 Play [deg]:  0.560,	 Stiffness [deg/Nm]:  0.176,	 pos_stiffness:  0.164,	 neg_stiffness:  0.188
    Test        2: 	 Play [deg]:  0.719,	 Stiffness [deg/Nm]:  0.181,	 pos_stiffness:  0.151,	 neg_stiffness:  0.211
    Test combined: 	 Play [deg]:  0.661,	 Stiffness [deg/Nm]:  0.182,	 pos_stiffness:  0.164,	 neg_stiffness:  0.201
  Test: preload increase 5
    Test        0: 	 Play [deg]:  0.756,	 Stiffness [deg/Nm]:  0.207,	 pos_stiffness:  0.188,	 neg_stiffness:  0.225
    Test        1: 	 Play [deg]:  0.531,	 Stiffness [deg/Nm]:  0.178,	 pos_stiffness:  0.164,	 neg_stiffness:  0.192
    Test        2: 	 Play [deg]:  0.579,	 Stiffness [deg/Nm]:  0.191,	 pos_stiffness:  0.166,	 neg_stiffness:  0.216
    Test combined: 	 Play [deg]:  0.621,	 Stiffness [deg/Nm]:  0.192,	 pos_stiffness:  0.173,	 neg_stiffness:  0.212
  Speed ramps
    initial             : 	 Coulomb Friction [Nm]:  6.393,	 coulomb_neg: -5.740,	 coulomb_pos:  7.046
    after run-in        : 	 Coulomb Friction [Nm]:  3.483,	 coulomb_neg: -3.604,	 coulomb_pos:  3.362
    preload increase 1  : 	 Coulomb Friction [Nm]:  4.595,	 coulomb_neg: -4.237,	 coulomb_pos:  4.954
    preload increase 2  : 	 Coulomb Friction [Nm]:  4.844,	 coulomb_neg: -4.559,	 coulomb_pos:  5.128
    preload increase 3  : 	 Coulomb Friction [Nm]:  6.243,	 coulomb_neg: -6.196,	 coulomb_pos:  6.289
    preload increase 4  : 	 Coulomb Friction [Nm]:  6.836,	 coulomb_neg: -6.964,	 coulomb_pos:  6.709
    preload increase 5  : 	 Coulomb Friction [Nm]:  7.527,	 coulomb_neg: -7.743,	 coulomb_pos:  7.311

Actuator: Baseline (Alloy 910)
  Test: initial - unreamed
    Test        0: 	 Play [deg]:  2.051,	 Stiffness [deg/Nm]:  0.146,	 pos_stiffness:  0.123,	 neg_stiffness:  0.169
    Test        1: 	 Play [deg]:  0.752,	 Stiffness [deg/Nm]:  0.150,	 pos_stiffness:  0.131,	 neg_stiffness:  0.169
    Test        2: 	 Play [deg]:  1.265,	 Stiffness [deg/Nm]:  0.157,	 pos_stiffness:  0.162,	 neg_stiffness:  0.152
    Test combined: 	 Play [deg]:  1.355,	 Stiffness [deg/Nm]:  0.152,	 pos_stiffness:  0.140,	 neg_stiffness:  0.163
  Test: after run-in warm
    Test        0: 	 Play [deg]:  2.733,	 Stiffness [deg/Nm]:  0.309,	 pos_stiffness:  0.243,	 neg_stiffness:  0.374
    Test        1: 	 Play [deg]:  1.146,	 Stiffness [deg/Nm]:  0.340,	 pos_stiffness:  0.296,	 neg_stiffness:  0.384
    Test        2: 	 Play [deg]:  2.589,	 Stiffness [deg/Nm]:  0.267,	 pos_stiffness:  0.250,	 neg_stiffness:  0.283
    Test combined: 	 Play [deg]:  2.152,	 Stiffness [deg/Nm]:  0.322,	 pos_stiffness:  0.292,	 neg_stiffness:  0.352
  Test: after run-in cold
    Test        0: 	 Play [deg]:  1.833,	 Stiffness [deg/Nm]:  0.185,	 pos_stiffness:  0.204,	 neg_stiffness:  0.166
    Test        1: 	 Play [deg]:  2.552,	 Stiffness [deg/Nm]:  0.176,	 pos_stiffness:  0.175,	 neg_stiffness:  0.177
    Test        2: 	 Play [deg]:  2.244,	 Stiffness [deg/Nm]:  0.175,	 pos_stiffness:  0.181,	 neg_stiffness:  0.169
    Test combined: 	 Play [deg]:  2.195,	 Stiffness [deg/Nm]:  0.180,	 pos_stiffness:  0.188,	 neg_stiffness:  0.171
  Test: after reaming output holes
    Test        0: 	 Play [deg]:  1.898,	 Stiffness [deg/Nm]:  0.159,	 pos_stiffness:  0.156,	 neg_stiffness:  0.162
    Test        1: 	 Play [deg]:  1.283,	 Stiffness [deg/Nm]:  0.130,	 pos_stiffness:  0.115,	 neg_stiffness:  0.145
    Test        2: 	 Play [deg]:  2.001,	 Stiffness [deg/Nm]:  0.162,	 pos_stiffness:  0.141,	 neg_stiffness:  0.182
    Test combined: 	 Play [deg]:  1.720,	 Stiffness [deg/Nm]:  0.151,	 pos_stiffness:  0.137,	 neg_stiffness:  0.164
  Speed ramps
    initial - unreamed  : 	 Coulomb Friction [Nm]:  2.704,	 coulomb_neg: -2.788,	 coulomb_pos:  2.619
    after run-in warm   : 	 Coulomb Friction [Nm]:  2.145,	 coulomb_neg: -2.301,	 coulomb_pos:  1.989
    after run-in cold   : 	 Coulomb Friction [Nm]:  2.321,	 coulomb_neg: -2.462,	 coulomb_pos:  2.180
    after reaming output holes: 	 Coulomb Friction [Nm]:  2.062,	 coulomb_neg: -2.303,	 coulomb_pos:  1.821

Actuator: Baseline (PC-CF)
  Test: initial
    Test        0: 	 Play [deg]:  1.894,	 Stiffness [deg/Nm]:  0.087,	 pos_stiffness:  0.085,	 neg_stiffness:  0.088
    Test        1: 	 Play [deg]:  2.770,	 Stiffness [deg/Nm]:  0.090,	 pos_stiffness:  0.065,	 neg_stiffness:  0.114
    Test        2: 	 Play [deg]:  3.006,	 Stiffness [deg/Nm]:  0.071,	 pos_stiffness:  0.071,	 neg_stiffness:  0.071
    Test combined: 	 Play [deg]:  2.556,	 Stiffness [deg/Nm]:  0.084,	 pos_stiffness:  0.075,	 neg_stiffness:  0.093
  Test: after run-in
    Test        0: 	 Play [deg]:  1.913,	 Stiffness [deg/Nm]:  0.084,	 pos_stiffness:  0.078,	 neg_stiffness:  0.090
    Test        1: 	 Play [deg]:  2.515,	 Stiffness [deg/Nm]:  0.092,	 pos_stiffness:  0.076,	 neg_stiffness:  0.107
    Test        2: 	 Play [deg]:  3.085,	 Stiffness [deg/Nm]:  0.070,	 pos_stiffness:  0.071,	 neg_stiffness:  0.069
    Test combined: 	 Play [deg]:  2.501,	 Stiffness [deg/Nm]:  0.083,	 pos_stiffness:  0.076,	 neg_stiffness:  0.089
  Speed ramps
    initial             : 	 Coulomb Friction [Nm]:  2.641,	 coulomb_neg: -2.610,	 coulomb_pos:  2.673
    after run-in        : 	 Coulomb Friction [Nm]:  1.899,	 coulomb_neg: -1.885,	 coulomb_pos:  1.913

Actuator: Conic Disk (PC-CF)
  Test: initial
    Test        0: 	 Play [deg]:  0.618,	 Stiffness [deg/Nm]:  0.104,	 pos_stiffness:  0.107,	 neg_stiffness:  0.101
    Test        1: 	 Play [deg]:  0.780,	 Stiffness [deg/Nm]:  0.110,	 pos_stiffness:  0.106,	 neg_stiffness:  0.113
    Test        2: 	 Play [deg]:  0.944,	 Stiffness [deg/Nm]:  0.103,	 pos_stiffness:  0.102,	 neg_stiffness:  0.104
    Test combined: 	 Play [deg]:  0.779,	 Stiffness [deg/Nm]:  0.106,	 pos_stiffness:  0.106,	 neg_stiffness:  0.106
  Test: after run-in
    Test        0: 	 Play [deg]:  1.759,	 Stiffness [deg/Nm]:  0.100,	 pos_stiffness:  0.102,	 neg_stiffness:  0.097
    Test        1: 	 Play [deg]:  0.938,	 Stiffness [deg/Nm]:  0.105,	 pos_stiffness:  0.103,	 neg_stiffness:  0.106
    Test        2: 	 Play [deg]:  1.732,	 Stiffness [deg/Nm]:  0.104,	 pos_stiffness:  0.103,	 neg_stiffness:  0.106
    Test combined: 	 Play [deg]:  1.474,	 Stiffness [deg/Nm]:  0.103,	 pos_stiffness:  0.103,	 neg_stiffness:  0.103
  Test: preload increase 1
    Test        0: 	 Play [deg]:  0.816,	 Stiffness [deg/Nm]:  0.106,	 pos_stiffness:  0.106,	 neg_stiffness:  0.105
    Test        1: 	 Play [deg]:  0.836,	 Stiffness [deg/Nm]:  0.108,	 pos_stiffness:  0.105,	 neg_stiffness:  0.110
    Test        2: 	 Play [deg]:  0.932,	 Stiffness [deg/Nm]:  0.104,	 pos_stiffness:  0.099,	 neg_stiffness:  0.108
    Test combined: 	 Play [deg]:  0.859,	 Stiffness [deg/Nm]:  0.106,	 pos_stiffness:  0.104,	 neg_stiffness:  0.108
  Test: preload increase 2
    Test        0: 	 Play [deg]:  0.764,	 Stiffness [deg/Nm]:  0.099,	 pos_stiffness:  0.099,	 neg_stiffness:  0.100
    Test        1: 	 Play [deg]:  0.602,	 Stiffness [deg/Nm]:  0.103,	 pos_stiffness:  0.095,	 neg_stiffness:  0.111
    Test        2: 	 Play [deg]:  0.719,	 Stiffness [deg/Nm]:  0.095,	 pos_stiffness:  0.092,	 neg_stiffness:  0.098
    Test combined: 	 Play [deg]:  0.693,	 Stiffness [deg/Nm]:  0.100,	 pos_stiffness:  0.097,	 neg_stiffness:  0.103
  Test: preload increase 3
    Test        0: 	 Play [deg]:  0.466,	 Stiffness [deg/Nm]:  0.095,	 pos_stiffness:  0.097,	 neg_stiffness:  0.094
    Test        1: 	 Play [deg]:  0.498,	 Stiffness [deg/Nm]:  0.101,	 pos_stiffness:  0.101,	 neg_stiffness:  0.101
    Test        2: 	 Play [deg]:  0.694,	 Stiffness [deg/Nm]:  0.092,	 pos_stiffness:  0.096,	 neg_stiffness:  0.088
    Test combined: 	 Play [deg]:  0.552,	 Stiffness [deg/Nm]:  0.097,	 pos_stiffness:  0.098,	 neg_stiffness:  0.096
  Test: preload increase 4
    Test        0: 	 Play [deg]:  0.467,	 Stiffness [deg/Nm]:  0.091,	 pos_stiffness:  0.087,	 neg_stiffness:  0.094
    Test        1: 	 Play [deg]:  0.332,	 Stiffness [deg/Nm]:  0.090,	 pos_stiffness:  0.093,	 neg_stiffness:  0.088
    Test        2: 	 Play [deg]:  0.650,	 Stiffness [deg/Nm]:  0.092,	 pos_stiffness:  0.092,	 neg_stiffness:  0.091
    Test combined: 	 Play [deg]:  0.481,	 Stiffness [deg/Nm]:  0.091,	 pos_stiffness:  0.091,	 neg_stiffness:  0.091
  Test: preload increase 5
    Test        0: 	 Play [deg]:  0.513,	 Stiffness [deg/Nm]:  0.096,	 pos_stiffness:  0.094,	 neg_stiffness:  0.098
    Test        1: 	 Play [deg]:  0.374,	 Stiffness [deg/Nm]:  0.093,	 pos_stiffness:  0.094,	 neg_stiffness:  0.093
    Test        2: 	 Play [deg]:  0.561,	 Stiffness [deg/Nm]:  0.092,	 pos_stiffness:  0.094,	 neg_stiffness:  0.090
    Test combined: 	 Play [deg]:  0.481,	 Stiffness [deg/Nm]:  0.094,	 pos_stiffness:  0.094,	 neg_stiffness:  0.094
  Speed ramps
    initial             : 	 Coulomb Friction [Nm]:  2.785,	 coulomb_neg: -2.752,	 coulomb_pos:  2.817
    after run-in        : 	 Coulomb Friction [Nm]:  3.019,	 coulomb_neg: -2.935,	 coulomb_pos:  3.103
    preload increase 1  : 	 Coulomb Friction [Nm]:  4.153,	 coulomb_neg: -3.759,	 coulomb_pos:  4.547
    preload increase 2  : 	 Coulomb Friction [Nm]:  5.371,	 coulomb_neg: -4.877,	 coulomb_pos:  5.865
    preload increase 3  : 	 Coulomb Friction [Nm]:  7.025,	 coulomb_neg: -6.466,	 coulomb_pos:  7.585
    preload increase 4  : 	 Coulomb Friction [Nm]:  9.577,	 coulomb_neg: -8.140,	 coulomb_pos: 11.015
    preload increase 5  : 	 Coulomb Friction [Nm]: 10.654,	 coulomb_neg: -9.665,	 coulomb_pos: 11.643

Actuator: Split Pinwheel (PC-CF)
  Test: initial
    Test        0: 	 Play [deg]:  1.118,	 Stiffness [deg/Nm]:  0.099,	 pos_stiffness:  0.102,	 neg_stiffness:  0.096
    Test        1: 	 Play [deg]:  0.908,	 Stiffness [deg/Nm]:  0.103,	 pos_stiffness:  0.100,	 neg_stiffness:  0.105
    Test        2: 	 Play [deg]:  0.988,	 Stiffness [deg/Nm]:  0.096,	 pos_stiffness:  0.084,	 neg_stiffness:  0.107
    Test combined: 	 Play [deg]:  1.004,	 Stiffness [deg/Nm]:  0.100,	 pos_stiffness:  0.098,	 neg_stiffness:  0.103
  Test: after run-in (and reassembled)
    Test        0: 	 Play [deg]:  1.486,	 Stiffness [deg/Nm]:  0.093,	 pos_stiffness:  0.102,	 neg_stiffness:  0.085
    Test        1: 	 Play [deg]:  1.957,	 Stiffness [deg/Nm]:  0.084,	 pos_stiffness:  0.080,	 neg_stiffness:  0.088
    Test        2: 	 Play [deg]:  1.247,	 Stiffness [deg/Nm]:  0.093,	 pos_stiffness:  0.091,	 neg_stiffness:  0.095
    Test combined: 	 Play [deg]:  1.559,	 Stiffness [deg/Nm]:  0.091,	 pos_stiffness:  0.092,	 neg_stiffness:  0.089
  Test: preload increase 1
    Test        0: 	 Play [deg]:  0.871,	 Stiffness [deg/Nm]:  0.094,	 pos_stiffness:  0.100,	 neg_stiffness:  0.089
    Test        1: 	 Play [deg]:  0.312,	 Stiffness [deg/Nm]:  0.096,	 pos_stiffness:  0.098,	 neg_stiffness:  0.095
    Test        2: 	 Play [deg]:  0.563,	 Stiffness [deg/Nm]:  0.083,	 pos_stiffness:  0.073,	 neg_stiffness:  0.094
    Test combined: 	 Play [deg]:  0.581,	 Stiffness [deg/Nm]:  0.092,	 pos_stiffness:  0.091,	 neg_stiffness:  0.093
  Test: preload increase 2
    Test        0: 	 Play [deg]:  0.222,	 Stiffness [deg/Nm]:  0.091,	 pos_stiffness:  0.098,	 neg_stiffness:  0.083
    Test        1: 	 Play [deg]:  0.199,	 Stiffness [deg/Nm]:  0.086,	 pos_stiffness:  0.088,	 neg_stiffness:  0.085
    Test        2: 	 Play [deg]:  0.207,	 Stiffness [deg/Nm]:  0.083,	 pos_stiffness:  0.077,	 neg_stiffness:  0.090
    Test combined: 	 Play [deg]:  0.208,	 Stiffness [deg/Nm]:  0.089,	 pos_stiffness:  0.090,	 neg_stiffness:  0.088
  Test: preload increase 3
    Test        0: 	 Play [deg]:  0.157,	 Stiffness [deg/Nm]:  0.090,	 pos_stiffness:  0.093,	 neg_stiffness:  0.087
    Test        1: 	 Play [deg]:  0.112,	 Stiffness [deg/Nm]:  0.084,	 pos_stiffness:  0.078,	 neg_stiffness:  0.090
    Test        2: 	 Play [deg]:  0.098,	 Stiffness [deg/Nm]:  0.084,	 pos_stiffness:  0.085,	 neg_stiffness:  0.083
    Test combined: 	 Play [deg]:  0.121,	 Stiffness [deg/Nm]:  0.090,	 pos_stiffness:  0.086,	 neg_stiffness:  0.095
  Speed ramps
    initial             : 	 Coulomb Friction [Nm]:  2.763,	 coulomb_neg: -2.792,	 coulomb_pos:  2.734
    after run-in (and reassembled): 	 Coulomb Friction [Nm]:  3.580,	 coulomb_neg: -3.714,	 coulomb_pos:  3.446
    preload increase 1  : 	 Coulomb Friction [Nm]:  5.129,	 coulomb_neg: -5.905,	 coulomb_pos:  4.352
    preload increase 2  : 	 Coulomb Friction [Nm]:  7.196,	 coulomb_neg: -6.840,	 coulomb_pos:  7.553
    preload increase 3  : 	 Coulomb Friction [Nm]:  9.353,	 coulomb_neg: -7.632,	 coulomb_pos: 11.074
['after run-in', '', 'initial', 'after run-in', 'preload increase 1', 'preload increase 2', 'preload increase 3', 'preload increase 4', 'preload increase 5', 'preload increase 6', 'preload increase 7', 'preload increase 8', 'preload increase 9', 'preload increase 10', 'preload increase 11', 'preload increase 12', '', 'initial', 'after run-in', 'preload increase 1', 'preload increase 2', 'preload increase 3', 'preload increase 4', 'preload increase 5', '', 'initial - unreamed', 'after run-in warm', 'after run-in cold', 'after reaming output holes', '', 'initial', 'after run-in', '', 'initial', 'after run-in', 'preload increase 1', 'preload increase 2', 'preload increase 3', 'preload increase 4', 'preload increase 5', '', 'initial', 'after run-in (and reassembled)', 'preload increase 1', 'preload increase 2', 'preload increase 3']
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [ ]:
actuators = [tests_split_onyx, tests_conic_onyx]
# Assuming tests_split_onyx, tests_conic_onyx, and results_df are defined
fig, ax1 = plt.subplots(figsize=(10, 5))
colors = ['tab:red', 'tab:blue', 'tab:green']


ax1.set_ylabel('Coulomb Friction [Nm]', color=colors[0])
ax1.tick_params(axis='y', labelcolor=colors[0])

ax2 = ax1.twinx()
ax2.set_ylabel('Play [deg]', color=colors[1])
ax2.tick_params(axis='y', labelcolor=colors[1])

ax3 = ax1.twinx()
ax3.spines['right'].set_position(('outward', 50))  # Offset the right spine of ax3
ax3.set_ylabel('Stiffness [deg/Nm]', color=colors[2])
ax3.tick_params(axis='y', labelcolor=colors[2])


for actuator in [tests_split_onyx, tests_conic_onyx]:
    results = results_df[results_df['actuator'] == actuator.configuration]
    results.drop(results[results['moment'] == 'initial'].index, inplace=True)
    x_ticks = np.linspace(0, 1, len(results))

    ax1.plot(results['Coulomb Friction [Nm]'], color=colors[0], label='\\ld{Coulomb Friction [Nm]}')
    ax2.plot(results['Play [deg]'], color=colors[1], label='\\ld{Play [deg]}')
    ax3.plot(results['Stiffness [deg/Nm]'], color=colors[2], label='\\ld{Stiffness [deg/Nm]}')

# Adding legends
fig.tight_layout()  # To ensure the right y-label is not clipped
lines, labels = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
lines3, labels3 = ax3.get_legend_handles_labels()
ax1.legend(lines + lines2 + lines3, labels + labels2 + labels3, loc='upper left')

plt.show()
C:\Users\jvolb\AppData\Local\Temp\ipykernel_16872\298074898.py:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  results.drop(results[results['moment'] == 'initial'].index, inplace=True)
C:\Users\jvolb\AppData\Local\Temp\ipykernel_16872\298074898.py:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  results.drop(results[results['moment'] == 'initial'].index, inplace=True)
No description has been provided for this image

data averaging example¶

Torque ramp repeats a torque increase in alternating diction for multiple itterations. THe following is how those repetitions are averaged into a single curve

In [ ]:
# select one of the raw dfs to be plotted here
df = tests_split_onyx.raw_torque_ramps['preload increase 1']

def average_data(df):
    data = []
    grouped = df.groupby('test_nr')

    for name, group in grouped:
        group = group.drop('test_nr', axis=1)
        group.index = group.index - group.index[0]

        old_len = len(group)
        group = group.resample('0.5ms').mean()
        group = group.interpolate(method='time')
        print(f'test {name} resampled from {old_len} to {len(group)} samples')

        data.append(group.values)

    # get consistent length
    min_len = min([len(d) for d in data])
    data = [d[:min_len] for d in data]
    print(f'setting everything to {min_len} samples')

    # average data using numpy
    data_mean = np.mean(np.array(data), axis=0)

    new_columns = df.columns.drop('test_nr')
    mean_df = pd.DataFrame(data_mean, columns=new_columns)

    # smooth data
    mean_df = mean_df.rolling(window=100, center=True).mean()
    mean_df = mean_df.bfill().ffill()

    return mean_df

TEST_NR_OFFSET = 100
play_tests = df[df['test_nr'] < TEST_NR_OFFSET].copy()
stiffness_tests = df[df['test_nr'] >= TEST_NR_OFFSET].copy()
stiffness_tests['test_nr'] = stiffness_tests['test_nr'] - TEST_NR_OFFSET

play_test_mean = average_data(play_tests)
stiffness_test_mean = average_data(stiffness_tests)


# plot torque ramp curves for each test, then overlay mean
fig, axs = plt.subplots(1, 2, figsize=(14, 5))
# colors = plt.cm.cividis(np.linspace(0, 1, play_tests['test_nr'].max() + 2))
colors = plt.cm.viridis(np.linspace(0, 1, play_tests['test_nr'].max() + 1))

for i in range(play_tests['test_nr'].max() + 1):
    test = play_tests[play_tests['test_nr'] == i]
    color = np.array([colors[i]])
    axs[0].scatter(test['Motor Torque [Nm]'], test['Deflection [deg]'], label=f'\\ld{{test {i+1}}}', color=color, alpha=0.6, s=4)
color = np.array([colors[-1]])
axs[0].plot(play_test_mean['Motor Torque [Nm]'], play_test_mean['Deflection [deg]'], label='\\ld{mean}', color='red')
axs[0].set_title('Play tests')

for i in range(stiffness_tests['test_nr'].max() + 1):
    test = stiffness_tests[stiffness_tests['test_nr'] == i]
    color = np.array([colors[i]]) 
    axs[1].scatter(test['Motor Torque [Nm]'], test['Deflection [deg]'], label=f'\\ld{{test {i+1}}}', color=color, alpha=0.6, s=4)
color = np.array([colors[-1]]) 
axs[1].plot(stiffness_test_mean['Motor Torque [Nm]'], stiffness_test_mean['Deflection [deg]'], label='\\ld{mean}', color='red')
axs[1].set_title('Stiffness tests')


axs[0].set_xlabel('Motor Torque [Nm]')
axs[0].set_ylabel('Deflection [deg]')
axs[1].set_xlabel('Motor Torque [Nm]')
axs[1].set_ylabel('Deflection [deg]')


axs[0].legend()
axs[1].legend()


# save plot
fig.tight_layout()

fig.savefig(f'figures/torq-displacement averaging.svg')

plt.show()
test 0 resampled from 1657 to 8125 samples
test 1 resampled from 1606 to 8127 samples
test 2 resampled from 1590 to 8125 samples
test 3 resampled from 1592 to 8127 samples
test 4 resampled from 1576 to 8125 samples
setting everything to 8125 samples
test 0 resampled from 7678 to 40127 samples
test 1 resampled from 7930 to 40157 samples
test 2 resampled from 7795 to 40125 samples
setting everything to 40125 samples
No description has been provided for this image

play and stiffness calculations¶

In [ ]:
play_test_mean, stiffness_test_mean = tests_split_onyx.torque_ramps['preload increase 1'][1]

def get_rising_slopes(df):
    # split data in to positive and negative slopes. remove the hysteresis part
    max_torque_idx = df['Desired Torque [Nm]'].idxmax()
    pos_slope = df.loc[:max_torque_idx]

    # find zero crossing of desired torque
    min_torque_idx = df['Desired Torque [Nm]'].idxmin()
    zero_torque_idx = df['Desired Torque [Nm]'][max_torque_idx:min_torque_idx].abs().idxmin()
    neg_slope = df.loc[zero_torque_idx:min_torque_idx]

    return pos_slope, neg_slope


# estimate play
play_pos_slope, play_neg_slope = get_rising_slopes(play_test_mean)
pos_play = play_pos_slope['Deflection [deg]'].iloc[0]
neg_play = play_neg_slope['Deflection [deg]'].iloc[0]
print(f'Play: {neg_play-pos_play} deg ({pos_play} pos, {neg_play} neg)')


# estimate stiffness
stiffness_pos_slope, stiffness_neg_slope = get_rising_slopes(stiffness_test_mean)
stiffness_pos_slope = stiffness_pos_slope[stiffness_pos_slope['Deflection [deg]'] > neg_play]
stiffness_neg_slope = stiffness_neg_slope[stiffness_neg_slope['Deflection [deg]'] < pos_play]

# do polyfit
pos_stifness, pos_offset = np.polyfit(stiffness_pos_slope['Motor Torque [Nm]'], stiffness_pos_slope['Deflection [deg]'], 1)
neg_stifness, neg_offset  = np.polyfit(stiffness_neg_slope['Motor Torque [Nm]'], stiffness_neg_slope['Deflection [deg]'], 1)

print(f'Positive stiffness: {pos_stifness} deg/Nm, offset: {pos_offset} deg')
print(f'Negative stiffness: {neg_stifness} deg/Nm, offset: {neg_offset} deg')


fig, axs = plt.subplots(1, 2, figsize=(14, 5))
play_test_mean.plot(x='Motor Torque [Nm]', y='Deflection [deg]', kind='line', ax=axs[0], label='\\ld{play test}', alpha=0.5)
play_pos_slope.plot(x='Motor Torque [Nm]', y='Deflection [deg]', kind='line', ax=axs[0], label='\\ld{positive slope}', color='r')
play_neg_slope.plot(x='Motor Torque [Nm]', y='Deflection [deg]', kind='line', ax=axs[0], label='\\ld{negative slope}', color='g')
# add line to show play
axs[0].plot([0, 0], [pos_play, neg_play], color='black', linestyle='--')
axs[0].text(0, 0, f'  {neg_play-pos_play:.2f} deg', color='black')
axs[0].set_title('Play test')

stiffness_test_mean.plot(x='Motor Torque [Nm]', y='Deflection [deg]', kind='line', ax=axs[1], label='\\ld{stiffness test}', alpha=0.5)
stiffness_pos_slope.plot(x='Motor Torque [Nm]', y='Deflection [deg]', kind='line', ax=axs[1], label='\\ld{positive slope}', color='r')
stiffness_neg_slope.plot(x='Motor Torque [Nm]', y='Deflection [deg]', kind='line', ax=axs[1], label='\\ld{negative slope}', color='g')
axs[1].plot(stiffness_pos_slope['Motor Torque [Nm]'], pos_offset + pos_stifness*stiffness_pos_slope['Motor Torque [Nm]'], color='r', linestyle='--')
axs[1].plot(stiffness_neg_slope['Motor Torque [Nm]'], neg_offset + neg_stifness*stiffness_neg_slope['Motor Torque [Nm]'], color='g', linestyle='--')
axs[1].set_title('Stiffness test')

axs[0].set_ylabel('Deflection [deg]')
axs[1].set_ylabel('Deflection [deg]')

axs[0].legend().set_visible(False)
axs[1].legend(loc='lower right')

fig.tight_layout()
fig.savefig(f'figures/play and stiffness estimation.svg')
plt.show()
Play: 1.3573462649754116 deg (-0.5976179491982261 pos, 0.7597283157771855 neg)
Positive stiffness: 0.19673331380730355 deg/Nm, offset: -0.003444036637144544 deg
Negative stiffness: 0.1780401724968055 deg/Nm, offset: -0.35204925313114405 deg
No description has been provided for this image

coulomb and viscous friction coefficient calculations¶

In [ ]:
def estimate_friction(df):
    # split data in positive and negative velocity
    positive_vt = df[df['Motor Speed [rpm]'] > 0]
    negative_vt = df[df['Motor Speed [rpm]'] < 0]

    # fit linear model
    pos_viscous, pos_coulomb,  = np.polyfit(positive_vt['Motor Speed [rpm]'], positive_vt['Motor Torque [Nm]'], 1)
    neg_viscous, neg_coulomb,  = np.polyfit(negative_vt['Motor Speed [rpm]'], negative_vt['Motor Torque [Nm]'], 1)

    # average
    coulomb = (pos_coulomb - neg_coulomb) / 2
    viscous = (pos_viscous + neg_viscous) / 2
    print(f'coulomb: {coulomb:.5f}[Nm], ({pos_coulomb:.5f}, {neg_coulomb:.5f})')
    print(f'viscous: {viscous:.5f} [Nm/(rev/s)], ({pos_viscous:.5f}, {neg_viscous:.5f})')

    #create model lines for pos and neg seperately
    pos_model = positive_vt.copy()
    pos_model['Friction Model'] = pos_viscous * pos_model['Motor Speed [rpm]'] + pos_coulomb
    neg_model = negative_vt.copy()
    neg_model['Friction Model'] = neg_viscous * neg_model['Motor Speed [rpm]'] + neg_coulomb

    # combine the two models
    fric_model = pd.concat([neg_model, pos_model])

    return fric_model

def average_data(df, groupby):
    data = []
    grouped = df.groupby(groupby)

    for name, group in grouped:
        group = group.drop(groupby, axis=1)
        group.index = group.index - group.index[0]

        old_len = len(group)
        group = group.resample('0.1ms').mean()
        group = group.interpolate(method='time')
        print(f'group {name} resampled from {old_len} to {len(group)} samples')

        data.append(group.values)

        if len(data) > 100:
            break

    data = data[5:100]

    # get consistent length
    min_len = min([len(d) for d in data])
    data = [d[:min_len] for d in data]
    print(f'setting everything to {min_len} samples')

    # average data using numpy
    data_mean = np.mean(np.array(data), axis=0)

    new_columns = df.columns.drop(groupby)
    mean_df = pd.DataFrame(data_mean, columns=new_columns)

    # smooth data
    mean_df = mean_df.rolling(window=100, center=True).mean()
    mean_df = mean_df.bfill().ffill()

    return mean_df


df = tests_split_pccf.speed_ramps['initial']

# plot measurements
fig, axs = plt.subplots(1, 1, figsize=(14, 5))
axs = [axs]

df.plot(x='Motor Speed [rpm]', y='Motor Torque [Nm]', kind='scatter', alpha=0.17, ax=axs[0])
df.plot(x='Motor Speed [rpm]', y='Averaged Torque [Nm]', kind='scatter', color='red', ax=axs[0], s=1)

# plot estimated friction
print(f'Estimated friction for :')
fric_model = estimate_friction(df)
fric_model.plot(x='Motor Speed [rpm]', y='Friction Model', color='green', ax=axs[0])

# # plot torque over position 
# df['REVOLUTIONS'] = np.floor(df['POSITION'])
# df['POSITION'] = df['POSITION'] - df['REVOLUTIONS']

# n_plots = int(df['REVOLUTIONS'].max())
# colors = plt.cm.viridis(np.linspace(0, 1, n_plots))
# for i in range(0, n_plots):
#     rev = df[(df['REVOLUTIONS'] == i) & (df['Motor Speed [rpm]'] > 0)]
#     rev.plot(x='POSITION', y='Motor Torque [Nm]', ax=axs[1], color=colors[i], alpha=0.4, legend=False)

# avg_fric = average_data(df, 'REVOLUTIONS')
# avg_fric.plot(x='POSITION', y='Motor Torque [Nm]', color='red', ax=axs[1])

fig.suptitle('Friction estimation')
fig.tight_layout()

fig.savefig(f'figures/friction estimation.svg')
    
plt.show()
Estimated friction for :
coulomb: 2.26512[Nm], (2.24675, -2.28350)
viscous: 1.62511 [Nm/(rev/s)], (1.60860, 1.64162)
No description has been provided for this image

averaging of multiple locking positions example with intermediate results

In [ ]:
selected_test = tests_conic_pccf.torque_ramps['preload increase 1']

fig, axs = plt.subplots(1, 2, figsize=(14, 5))
for name, (play_test, stiffness_test) in selected_test.items():
    if name == 'combined':
        a = 1
        color = 'black'
        label = '\\ld{averaged}'
    else:
        a = 0.7
        color = None
        label = f'\\ld{{test position {name+1}}}'
    play_test.plot(x='Motor Torque [Nm]', y='Deflection [deg]', kind='line', ax=axs[0], label=label, alpha=a, color=color)
    stiffness_test.plot(x='Motor Torque [Nm]', y='Deflection [deg]', kind='line', ax=axs[1], label=label, alpha=a, color=color)

fig.suptitle('averaging multiple torque tests')
axs[0].set_title('Play tests')
axs[1].set_title('Stiffness tests')
axs[0].set_ylabel('Deflection [deg]')
axs[1].set_ylabel('Deflection [deg]')

axs[0].legend().set_visible(False)
axs[1].legend(loc='lower right')

fig.tight_layout()
fig.savefig(f'figures/averaging multiple torque tests.svg')
plt.show()
No description has been provided for this image
In [ ]:
import matplotlib.dates as mdates

# plot runin test as example
df = tests_split_onyx.runin_tests
fig, ax = plt.subplots(1, 1, figsize=(7, 5))

x_values = df.index.total_seconds() / 60

ax.plot(x_values, df['Motor Torque [Nm]'], label='\\ld{Motor Torque [Nm]}')
ax.plot(x_values, df['Averaged Torque [Nm]'], label='\\ld{Averaged Torque [Nm]}')
ax.set_ylabel('Torque [Nm]')
ax.set_xlabel('Time [s]')

# # Formatting the x-axis labels to hour:minute format
# hour_minute_formatter = mdates.DateFormatter('%H:%M')
# ax.xaxis.set_major_formatter(hour_minute_formatter)

# temperatures
ax2 = ax.twinx()
ax2.plot(x_values, df['Controller Temperature [c]'], color='red', label='\\ld{Controller Temperature [C]}')
ax2.plot(x_values, df['Motor Temperature [c]'], color='blue', label='\\ld{Motor Temperature [C]}')
ax2.set_ylabel('Temperature [C]')

#temperatures
# ax3 = ax.twinx()
# ax3.spines['right'].set_position(('outward', 50))  # Offset the right spine of ax3
# ax3.plot(df['Motor Speed [rpm]'], color='red', label='\\ld{Motor Speed [rpm]}')

fig.suptitle('Runin test')
fig.legend(loc='upper right')


fig.tight_layout()
fig.savefig(f'figures/runin test.svg')

plt.show()
        
No description has been provided for this image
In [ ]: